void filinit(File *f, char *t) { File *g; f->wins.wnext = f->wins.wprev = &f->wins; f->name = strdup(t); for(g = flist.next; g != &flist && filcmp(g, f) < 0; g = g->next) ; f->prev = g->prev; f->next = g; g->prev->next = f; g->prev = f; }
/*! \brief Config file parser * \param gobConf Config file to parse * \param stk STK/ITK archive file to be created * \param chunkCount Number of chunks to be written in the archive file * \return A list of chunks * * This function reads the '.gob' config file (generated by extract_gob_stk). * It creates the output archive file and a list of chunks containing the file * and compression information. * In order to have a slightly better compression ration in some cases (Playtoons), it * also detects duplicate files. */ CompressGob::Chunk *CompressGob::readChunkConf(Common::File &gobConf, Common::Filename &stkName, uint16 &chunkCount) { Chunk *chunks = new Chunk; Chunk *curChunk = chunks; Chunk *parseChunk; Common::File src1; Common::Filename srcName(""); char buffer[1024]; chunkCount = 1; // First read: Output filename gobConf.scanString(buffer); stkName.setFullName(buffer); srcName.setFullPath(stkName.getPath()); // Second read: signature gobConf.scanString(buffer); std::string signature(buffer); if (signature == confSTK21) error("STK21 not yet handled"); else if (signature != confSTK10) error("Unknown format signature %s", signature.c_str()); print("Checking duplicate files"); // All the other reads concern file + compression flag gobConf.scanString(buffer); while (!gobConf.eos()) { strcpy(curChunk->name, buffer); srcName.setFullName(buffer); gobConf.scanString(buffer); if ((strcmp(buffer, "1") == 0 )|| (_execMode & MODE_FORCE)) curChunk->packed = true; else curChunk->packed = false; src1.open(srcName, "rb"); src1.seek(0, SEEK_END); // if file is too small, force 'Store' method if ((curChunk->realSize = src1.pos()) < 8) curChunk->packed = 0; parseChunk = chunks; while (parseChunk != curChunk) { if ((parseChunk->realSize == curChunk->realSize) & (parseChunk->packed != 2)) { if (strcmp(parseChunk->name, curChunk->name) == 0) error("Duplicate filename found in conf file: %s", parseChunk->name); srcName.setFullName(parseChunk->name); if (filcmp(src1, srcName)) { // If files are identical, use the same compressed chunk instead of re-compressing the same thing curChunk->packed = 2; curChunk->replChunk = parseChunk; print("Identical files : %s %s (%d bytes)", curChunk->name, parseChunk->name, curChunk->realSize); break; } } parseChunk = parseChunk->next; } src1.close(); gobConf.scanString(buffer); if (!gobConf.eos()) { curChunk->next = new Chunk; curChunk = curChunk->next; chunkCount++; } } return chunks; }