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 <map>
00042 #include <iostream>
00043 
00044 #ifdef HAVE_CONFIG_H
00045 # include <config.h>
00046 #endif
00047 
00048 #if POSIX
00049 # include <sys/types.h>
00050 # include <sys/stat.h>
00051 # include <fcntl.h>
00052 # include <unistd.h>
00053 #endif // POSIX
00054 
00055 #include <stdint.h>
00056 
00057 #ifdef WIN32
00058 # include <windows.h>
00059   typedef unsigned int   uint;
00060 #endif // WIN32
00061 
00062 #include <stdio.h>
00063 
00064 #if WORDS_BIGENDIAN
00065 # define CHUNK_ID_RIFF  0x52494646
00066 # define CHUNK_ID_RIFX  0x52494658
00067 # define CHUNK_ID_LIST  0x4C495354
00068 #else  // little endian
00069 # define CHUNK_ID_RIFF  0x46464952
00070 # define CHUNK_ID_RIFX  0x58464952
00071 # define CHUNK_ID_LIST  0x5453494C
00072 #endif // WORDS_BIGENDIAN
00073 
00074 #define CHUNK_HEADER_SIZE       8
00075 #define LIST_HEADER_SIZE        12
00076 #define RIFF_HEADER_SIZE        12
00077 
00078 
00098 namespace RIFF {
00099 
00100     /* just symbol prototyping */
00101     class Chunk;
00102     class List;
00103     class File;
00104 
00105     typedef std::string String;
00106 
00108     typedef enum {
00109         stream_mode_read       = 0,
00110         stream_mode_read_write = 1,
00111         stream_mode_closed     = 2
00112     } stream_mode_t;
00113 
00115     typedef enum {
00116         stream_ready       = 0,
00117         stream_end_reached = 1,
00118         stream_closed      = 2
00119     } stream_state_t;
00120 
00122     typedef enum {
00123         stream_start    = 0,
00124         stream_curpos   = 1,
00125         stream_backward = 2,
00126         stream_end      = 3
00127     } stream_whence_t;
00128 
00130     typedef enum {
00131         endian_little = 0,
00132         endian_big    = 1,
00133         endian_native = 2
00134     } endian_t;
00135 
00141     class Chunk {
00142         public:
00143             Chunk(File* pFile, unsigned long StartPos, List* Parent);
00144             String         GetChunkIDString();
00145             uint32_t       GetChunkID() { return ChunkID; };            
00146             List*          GetParent()  { return pParent; };            
00147             unsigned long  GetSize()    { return CurrentChunkSize; };   
00148             unsigned long  GetNewSize() { return NewChunkSize;     };   
00149             unsigned long  GetPos()     { return ulPos; };              
00150             unsigned long  GetFilePos() { return ulStartPos + ulPos; }; 
00151             unsigned long  SetPos(unsigned long Where, stream_whence_t Whence = stream_start);
00152             unsigned long  RemainingBytes();
00153             stream_state_t GetState();
00154             unsigned long  Read(void* pData, unsigned long WordCount, unsigned long WordSize);
00155             unsigned long  ReadInt8(int8_t* pData,     unsigned long WordCount = 1);
00156             unsigned long  ReadUint8(uint8_t* pData,   unsigned long WordCount = 1);
00157             unsigned long  ReadInt16(int16_t* pData,   unsigned long WordCount = 1);
00158             unsigned long  ReadUint16(uint16_t* pData, unsigned long WordCount = 1);
00159             unsigned long  ReadInt32(int32_t* pData,   unsigned long WordCount = 1);
00160             unsigned long  ReadUint32(uint32_t* pData, unsigned long WordCount = 1);
00161             int8_t         ReadInt8();
00162             uint8_t        ReadUint8();
00163             int16_t        ReadInt16();
00164             uint16_t       ReadUint16();
00165             int32_t        ReadInt32();
00166             uint32_t       ReadUint32();
00167             unsigned long  Write(void* pData, unsigned long WordCount, unsigned long WordSize);
00168             unsigned long  WriteInt8(int8_t* pData,     unsigned long WordCount = 1);
00169             unsigned long  WriteUint8(uint8_t* pData,   unsigned long WordCount = 1);
00170             unsigned long  WriteInt16(int16_t* pData,   unsigned long WordCount = 1);
00171             unsigned long  WriteUint16(uint16_t* pData, unsigned long WordCount = 1);
00172             unsigned long  WriteInt32(int32_t* pData,   unsigned long WordCount = 1);
00173             unsigned long  WriteUint32(uint32_t* pData, unsigned long WordCount = 1);
00174             void*          LoadChunkData();
00175             void           ReleaseChunkData();
00176             void           Resize(int iNewSize);
00177             virtual ~Chunk();
00178         protected:
00179             uint32_t      ChunkID;
00180             uint32_t      CurrentChunkSize;             /* in bytes */
00181             uint32_t      NewChunkSize;                 /* in bytes (if chunk was scheduled to be resized) */
00182             List*         pParent;
00183             File*         pFile;
00184             unsigned long ulStartPos;           /* actual position in file where chunk (without header) starts */
00185             unsigned long ulPos;                /* # of bytes from ulStartPos */
00186             uint8_t*      pChunkData;
00187             unsigned long ulChunkDataSize;
00188 
00189             Chunk(File* pFile);
00190             Chunk(File* pFile, List* pParent, uint32_t uiChunkID, uint uiBodySize);
00191             void          ReadHeader(unsigned long fPos);
00192             void          WriteHeader(unsigned long fPos);
00193             unsigned long ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize);
00194             inline void   swapBytes_16(void* Word) {
00195                 uint8_t byteCache = *((uint8_t*) Word);
00196                 *((uint8_t*) Word)     = *((uint8_t*) Word + 1);
00197                 *((uint8_t*) Word + 1) = byteCache;
00198             }
00199             inline void   swapBytes_32(void* Word) {
00200                 uint8_t byteCache = *((uint8_t*) Word);
00201                 *((uint8_t*) Word)     = *((uint8_t*) Word + 3);
00202                 *((uint8_t*) Word + 3) = byteCache;
00203                 byteCache = *((uint8_t*) Word + 1);
00204                 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
00205                 *((uint8_t*) Word + 2) = byteCache;
00206             }
00207             inline void   swapBytes(void* Word, unsigned long WordSize) {
00208                 uint8_t byteCache;
00209                 unsigned long lo = 0, hi = WordSize - 1;
00210                 for (; lo < hi; hi--, lo++) {
00211                     byteCache = *((uint8_t*) Word + lo);
00212                     *((uint8_t*) Word + lo) = *((uint8_t*) Word + hi);
00213                     *((uint8_t*) Word + hi) = byteCache;
00214                 }
00215             }
00216             inline String convertToString(uint32_t word) {
00217                 String result;
00218                 for (int i = 0; i < 4; i++) {
00219                     uint8_t byte = *((uint8_t*)(&word) + i);
00220                     char c = byte;
00221                     result += c;
00222                 }
00223                 return result;
00224             }
00225             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00226             virtual void __resetPos(); 
00227 
00228             friend class List;
00229     };
00230 
00236     class List : public Chunk {
00237         public:
00238             List(File* pFile, unsigned long StartPos, List* Parent);
00239             String       GetListTypeString();
00240             uint32_t     GetListType() { return ListType; }   
00241             Chunk*       GetSubChunk(uint32_t ChunkID);
00242             List*        GetSubList(uint32_t ListType);
00243             Chunk*       GetFirstSubChunk();
00244             Chunk*       GetNextSubChunk();
00245             List*        GetFirstSubList();
00246             List*        GetNextSubList();
00247             unsigned int CountSubChunks();
00248             unsigned int CountSubChunks(uint32_t ChunkID);
00249             unsigned int CountSubLists();
00250             unsigned int CountSubLists(uint32_t ListType);
00251             Chunk*       AddSubChunk(uint32_t uiChunkID, uint uiBodySize);
00252             List*        AddSubList(uint32_t uiListType);
00253             void         DeleteSubChunk(Chunk* pSubChunk);
00254             void         MoveSubChunk(Chunk* pSrc, Chunk* pDst);
00255             virtual ~List();
00256         protected:
00257             typedef std::map<uint32_t, RIFF::Chunk*>  ChunkMap;
00258             typedef std::list<Chunk*>                 ChunkList;
00259 
00260             uint32_t   ListType;
00261             ChunkList* pSubChunks;
00262             ChunkMap*  pSubChunksMap;
00263             ChunkList::iterator ChunksIterator;
00264             ChunkList::iterator ListIterator;
00265 
00266             List(File* pFile);
00267             List(File* pFile, List* pParent, uint32_t uiListID);
00268             void ReadHeader(unsigned long fPos);
00269             void WriteHeader(unsigned long fPos);
00270             void LoadSubChunks();
00271             void LoadSubChunksRecursively();
00272             virtual unsigned long WriteChunk(unsigned long ulWritePos, unsigned long ulCurrentDataOffset);
00273             virtual void __resetPos(); 
00274     };
00275 
00282     class File : public List {
00283         public:
00284             File(uint32_t FileType);
00285             File(const String& path);
00286             stream_mode_t GetMode();
00287             bool          SetMode(stream_mode_t NewMode);
00288             void SetByteOrder(endian_t Endian);
00289             String GetFileName();
00290             virtual void Save();
00291             virtual void Save(const String& path);
00292             virtual ~File();
00293         protected:
00294             #if POSIX
00295             int    hFileRead;  
00296             int    hFileWrite; 
00297             #elif defined(WIN32)
00298             HANDLE hFileRead;  
00299             HANDLE hFileWrite; 
00300             #else
00301             FILE*  hFileRead;  
00302             FILE*  hFileWrite; 
00303             #endif // POSIX
00304             String Filename;
00305             bool   bEndianNative;
00306 
00307             void LogAsResized(Chunk* pResizedChunk);
00308             void UnlogResized(Chunk* pResizedChunk);
00309             friend class Chunk;
00310             friend class List;
00311         private:
00312             stream_mode_t  Mode;
00313             ChunkList      ResizedChunks; 
00314 
00315             unsigned long GetFileSize();
00316             void ResizeFile(unsigned long ulNewSize);
00317             #if POSIX
00318             unsigned long __GetFileSize(int hFile);
00319             #elif defined(WIN32)
00320             unsigned long __GetFileSize(HANDLE hFile);
00321             #else
00322             unsigned long __GetFileSize(FILE* hFile);
00323             #endif
00324     };
00325 
00329     class Exception {
00330         public:
00331             String Message;
00332 
00333             Exception(String Message) { Exception::Message = Message; };
00334             void PrintMessage();
00335             virtual ~Exception() {};
00336     };
00337 
00338     String libraryName();
00339     String libraryVersion();
00340 
00341 } // namespace RIFF
00342 #endif // __RIFF_H__

Generated on Sun Dec 9 06:56:29 2007 for libgig by  doxygen 1.5.4