00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <lib3ds/chunk.h>
00023 #include <lib3ds/io.h>
00024 #include <lib3ds/chunktable.h>
00025 #include <string.h>
00026 #include <stdarg.h>
00027
00028
00029
00030
00031
00032
00038 static Lib3dsBool enable_dump=LIB3DS_FALSE;
00039 static Lib3dsBool enable_unknown=LIB3DS_FALSE;
00040 static char lib3ds_chunk_level[128]="";
00041
00042
00043 static void
00044 lib3ds_chunk_debug_enter(Lib3dsChunk *c)
00045 {
00046 strcat(lib3ds_chunk_level, " ");
00047 }
00048
00049
00050 static void
00051 lib3ds_chunk_debug_leave(Lib3dsChunk *c)
00052 {
00053 lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
00054 }
00055
00056
00057 static void
00058 lib3ds_chunk_debug_dump(Lib3dsChunk *c)
00059 {
00060 if (enable_dump) {
00061 printf("%s%s (0x%X) size=%lu\n",
00062 lib3ds_chunk_level,
00063 lib3ds_chunk_name(c->chunk),
00064 c->chunk,
00065 c->size
00066 );
00067 }
00068 }
00069
00070
00074 void
00075 lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown)
00076 {
00077 enable_dump=enable;
00078 enable_unknown=unknown;
00079 }
00080
00081
00092 Lib3dsBool
00093 lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io)
00094 {
00095 ASSERT(c);
00096 ASSERT(io);
00097 c->cur=lib3ds_io_tell(io);
00098 c->chunk=lib3ds_io_read_word(io);
00099 c->size=lib3ds_io_read_dword(io);
00100 c->end=c->cur+c->size;
00101 c->cur+=6;
00102 if (lib3ds_io_error(io) || (c->size<6)) {
00103 return(LIB3DS_FALSE);
00104 }
00105 return(LIB3DS_TRUE);
00106
00107 }
00108
00109
00113 Lib3dsBool
00114 lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, Lib3dsIo *io)
00115 {
00116 ASSERT(c);
00117 ASSERT(io);
00118 if (!lib3ds_chunk_read(c, io)) {
00119 return(LIB3DS_FALSE);
00120 }
00121 lib3ds_chunk_debug_enter(c);
00122 return((chunk==0) || (c->chunk==chunk));
00123 }
00124
00125
00129 void
00130 lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io)
00131 {
00132 c->cur=lib3ds_io_tell(io);
00133 }
00134
00135
00139 Lib3dsWord
00140 lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io)
00141 {
00142 Lib3dsChunk d;
00143
00144 if (c->cur>=c->end) {
00145 ASSERT(c->cur==c->end);
00146 return(0);
00147 }
00148
00149 lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET);
00150 d.chunk=lib3ds_io_read_word(io);
00151 d.size=lib3ds_io_read_dword(io);
00152 lib3ds_chunk_debug_dump(&d);
00153 c->cur+=d.size;
00154 return(d.chunk);
00155 }
00156
00157
00161 void
00162 lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io)
00163 {
00164 lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR);
00165 }
00166
00167
00171 void
00172 lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io)
00173 {
00174 lib3ds_chunk_debug_leave(c);
00175 lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET);
00176 }
00177
00178
00189 Lib3dsBool
00190 lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io)
00191 {
00192 ASSERT(c);
00193 if (!lib3ds_io_write_word(io, c->chunk)) {
00194 LIB3DS_ERROR_LOG;
00195 return(LIB3DS_FALSE);
00196 }
00197 if (!lib3ds_io_write_dword(io, c->size)) {
00198 LIB3DS_ERROR_LOG;
00199 return(LIB3DS_FALSE);
00200 }
00201 return(LIB3DS_TRUE);
00202 }
00203
00204
00208 Lib3dsBool
00209 lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io)
00210 {
00211 ASSERT(c);
00212 c->size=0;
00213 c->cur=lib3ds_io_tell(io);
00214 if (!lib3ds_io_write_word(io, c->chunk)) {
00215 return(LIB3DS_FALSE);
00216 }
00217 if (!lib3ds_io_write_dword(io, c->size)) {
00218 return(LIB3DS_FALSE);
00219 }
00220 return(LIB3DS_TRUE);
00221 }
00222
00223
00227 Lib3dsBool
00228 lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io)
00229 {
00230 ASSERT(c);
00231 c->size=lib3ds_io_tell(io) - c->cur;
00232 lib3ds_io_seek(io, c->cur+2, LIB3DS_SEEK_SET);
00233 if (!lib3ds_io_write_dword(io, c->size)) {
00234 LIB3DS_ERROR_LOG;
00235 return(LIB3DS_FALSE);
00236 }
00237
00238 c->cur+=c->size;
00239 lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET);
00240 if (lib3ds_io_error(io)) {
00241 LIB3DS_ERROR_LOG;
00242 return(LIB3DS_FALSE);
00243 }
00244 return(LIB3DS_TRUE);
00245 }
00246
00247
00251 Lib3dsBool
00252 lib3ds_chunk_write_switch(Lib3dsWord chunk, Lib3dsIo *io)
00253 {
00254 Lib3dsChunk c;
00255 c.chunk=chunk;
00256 c.size=6;
00257 return lib3ds_chunk_write(&c,io);
00258 }
00259
00260
00264 const char*
00265 lib3ds_chunk_name(Lib3dsWord chunk)
00266 {
00267 Lib3dsChunkTable *p;
00268
00269 for (p=lib3ds_chunk_table; p->name!=0; ++p) {
00270 if (p->chunk==chunk) {
00271 return(p->name);
00272 }
00273 }
00274 return("***UNKNOWN***");
00275 }
00276
00277
00281 void
00282 lib3ds_chunk_unknown(Lib3dsWord chunk)
00283 {
00284 if (enable_unknown) {
00285 printf("%s***WARNING*** Unknown Chunk: %s (0x%X)\n",
00286 lib3ds_chunk_level,
00287 lib3ds_chunk_name(chunk),
00288 chunk
00289 );
00290 }
00291 }
00292
00293
00297 void
00298 lib3ds_chunk_dump_info(const char *format, ...)
00299 {
00300 if (enable_dump) {
00301 char s[1024];
00302 va_list marker;
00303
00304 va_start(marker, format);
00305 vsprintf(s, format, marker);
00306 va_end(marker);
00307
00308 printf("%s%s\n", lib3ds_chunk_level, s);
00309 }
00310 }
00311
00312
00313
00314
00315
00316
00317