00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00049
00050
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
00073 class Chunk;
00074 class List;
00075
00076 typedef std::string String;
00077
00079 typedef enum {
00080 stream_ready = 0,
00081 stream_end_reached = 1,
00082 stream_closed = 2
00083 } stream_state_t;
00084
00086 typedef enum {
00087 stream_start = 0,
00088 stream_curpos = 1,
00089 stream_backward = 2,
00090 stream_end = 3
00091 } stream_whence_t;
00092
00094 class Chunk {
00095 public:
00096 #if POSIX
00097 Chunk(int hFile, unsigned long StartPos, bool EndianNative, List* Parent);
00098 #else
00099 Chunk(FILE* hFile, unsigned long StartPos, bool EndianNative, List* Parent);
00100 #endif // POSIX
00101 String GetChunkIDString();
00102 uint32_t GetChunkID() { return ChunkID; };
00103 List* GetParent() { return pParent; };
00104 unsigned long GetSize() { return ChunkSize; };
00105 unsigned long GetPos() { return ulPos; };
00106 unsigned long GetFilePos() { return ulStartPos + ulPos; };
00107 unsigned long SetPos(unsigned long Where, stream_whence_t Whence = stream_start);
00108 unsigned long RemainingBytes();
00109 stream_state_t GetState();
00110 unsigned long Read(void* pData, unsigned long WordCount, unsigned long WordSize);
00111 unsigned long ReadInt8(int8_t* pData, unsigned long WordCount = 1);
00112 unsigned long ReadUint8(uint8_t* pData, unsigned long WordCount = 1);
00113 unsigned long ReadInt16(int16_t* pData, unsigned long WordCount = 1);
00114 unsigned long ReadUint16(uint16_t* pData, unsigned long WordCount = 1);
00115 unsigned long ReadInt32(int32_t* pData, unsigned long WordCount = 1);
00116 unsigned long ReadUint32(uint32_t* pData, unsigned long WordCount = 1);
00117 int8_t ReadInt8();
00118 uint8_t ReadUint8();
00119 int16_t ReadInt16();
00120 uint16_t ReadUint16();
00121 int32_t ReadInt32();
00122 uint32_t ReadUint32();
00123 void* LoadChunkData();
00124 void ReleaseChunkData();
00125 virtual ~Chunk();
00126 protected:
00127 uint32_t ChunkID;
00128 uint32_t ChunkSize;
00129 List* pParent;
00130 #if POSIX
00131 int hFile;
00132 #else
00133 FILE* hFile;
00134 #endif // POSIX
00135 unsigned long ulStartPos;
00136 unsigned long ulPos;
00137 bool bEndianNative;
00138 uint8_t* pChunkData;
00139
00140 Chunk();
00141 void ReadHeader(unsigned long fPos);
00142 unsigned long ReadSceptical(void* pData, unsigned long WordCount, unsigned long WordSize);
00143 inline void swapBytes_16(void* Word) {
00144 uint8_t byteCache = *((uint8_t*) Word);
00145 *((uint8_t*) Word) = *((uint8_t*) Word + 1);
00146 *((uint8_t*) Word + 1) = byteCache;
00147 }
00148 inline void swapBytes_32(void* Word) {
00149 uint8_t byteCache = *((uint8_t*) Word);
00150 *((uint8_t*) Word) = *((uint8_t*) Word + 3);
00151 *((uint8_t*) Word + 3) = byteCache;
00152 byteCache = *((uint8_t*) Word + 1);
00153 *((uint8_t*) Word + 1) = *((uint8_t*) Word + 2);
00154 *((uint8_t*) Word + 2) = byteCache;
00155 }
00156 inline void swapBytes(void* Word, unsigned long WordSize) {
00157 uint8_t byteCache;
00158 unsigned long lo = 0, hi = WordSize - 1;
00159 for (; lo < hi; hi--, lo++) {
00160 byteCache = *((uint8_t*) Word + lo);
00161 *((uint8_t*) Word + lo) = *((uint8_t*) Word + hi);
00162 *((uint8_t*) Word + hi) = byteCache;
00163 }
00164 }
00165 inline String convertToString(uint32_t word) {
00166 String result;
00167 for (int i = 0; i < 4; i++) {
00168 uint8_t byte = *((uint8_t*)(&word) + i);
00169 char c = byte;
00170 result += c;
00171 }
00172 return result;
00173 }
00174 };
00175
00177 class List : public Chunk {
00178 public:
00179 #if POSIX
00180 List(int hFile, unsigned long StartPos, bool EndianNative, List* Parent);
00181 #else
00182 List(FILE* hFile, unsigned long StartPos, bool EndianNative, List* Parent);
00183 #endif // POSIX
00184 String GetListTypeString();
00185 uint32_t GetListType() { return ListType; }
00186 Chunk* GetSubChunk(uint32_t ChunkID);
00187 List* GetSubList(uint32_t ListType);
00188 Chunk* GetFirstSubChunk();
00189 Chunk* GetNextSubChunk();
00190 List* GetFirstSubList();
00191 List* GetNextSubList();
00192 unsigned int CountSubChunks();
00193 unsigned int CountSubChunks(uint32_t ChunkID);
00194 unsigned int CountSubLists();
00195 unsigned int CountSubLists(uint32_t ListType);
00196 virtual ~List();
00197 protected:
00198 typedef std::map<uint32_t, RIFF::Chunk*> ChunkMap;
00199 typedef std::list<Chunk*> ChunkList;
00200
00201 uint32_t ListType;
00202 ChunkList* pSubChunks;
00203 ChunkMap* pSubChunksMap;
00204 ChunkList::iterator ChunksIterator;
00205 ChunkList::iterator ListIterator;
00206
00207 List();
00208 void ReadHeader(unsigned long fPos);
00209 void LoadSubChunks();
00210 };
00211
00213 class File : public List {
00214 public:
00215 File(const String& path);
00216 virtual ~File();
00217 const String Filename;
00218 private:
00219 unsigned long GetFileSize();
00220 };
00221
00223 class Exception {
00224 public:
00225 String Message;
00226
00227 Exception(String Message) { Exception::Message = Message; };
00228 void PrintMessage();
00229 virtual ~Exception() {};
00230 };
00231
00232 String libraryName();
00233 String libraryVersion();
00234
00235 }
00236 #endif // __RIFF_H__