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

Generated on Thu Aug 16 07:21:39 2007 for libgig by  doxygen 1.5.3