00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022
00023
00024 #include "IFF.h"
00025
00026 #ifndef ALPHA_LINUX_CXX
00027 # include <cstdio>
00028 #endif
00029 #include <iostream>
00030 #include "exceptions.h"
00031 #include "utils.h"
00032
00033 using std::string;
00034 using std::vector;
00035
00036 #ifndef UNDER_CE
00037 using std::cout;
00038 using std::cerr;
00039 using std::endl;
00040 using std::FILE;
00041 using std::memcmp;
00042 using std::memset;
00043 using std::size_t;
00044 #endif
00045
00046 IFF::IFF(const string &n) : U7file(n)
00047 {
00048 IndexIFFFile();
00049 }
00050
00051 void IFF::IndexIFFFile(void)
00052 {
00053 FILE *fp;
00054 char ckid[4];
00055 fp=U7open(filename.c_str(),"rb");
00056
00057 std::fread(ckid,4,1,fp);
00058 if(memcmp(ckid,"FORM",4))
00059 throw wrong_file_type_exception(filename,"IFF");
00060
00061 #ifdef DEBUG
00062 cout << "Okay. It looks like an IFF file chunk" << endl;
00063 #endif
00064 long full_length;
00065 full_length = Read4high(fp);
00066 #ifdef DEBUG
00067 cout << "length looks like: " << full_length << endl;
00068 #endif
00069 fseek(fp,4,SEEK_CUR);
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 while(ftell(fp) < full_length)
00085 {
00086 Reference r;
00087 char type[5];
00088 memset(type,0,sizeof(type));
00089
00090 std::fread(type,4,1,fp);
00091 if(type[0]<32)
00092 {
00093
00094 fseek(fp,-3,SEEK_CUR);
00095 continue;
00096 }
00097
00098 r.size=Read4high(fp);
00099 r.offset=ftell(fp);
00100
00101 if(r.size==0||r.offset==0)
00102 break;
00103 object_list.push_back(r);
00104 fseek(fp,r.offset+r.size,SEEK_SET);
00105 }
00106
00107 fclose(fp);
00108 }
00109
00110 char * IFF::retrieve(uint32 objnum, size_t &len)
00111 {
00112 FILE *fp;
00113 char *buffer;
00114
00115 if (objnum >= object_list.size())
00116 throw exult_exception("objnum too large in IFF::retrieve()");
00117
00118 fp = U7open(filename.c_str(), "rb");
00119 fseek(fp, object_list[objnum].offset, SEEK_SET);
00120 len = object_list[objnum].size;
00121 buffer = new char[len];
00122 std::fread(buffer, len, 1, fp);
00123 fclose(fp);
00124
00125 return buffer;
00126 }
00127