Esempio n. 1
0
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;
}
Esempio n. 2
0
/*! \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;
}