コード例 #1
0
ファイル: test_index.c プロジェクト: Bludge0n/AREsoft
static bool
is_equal(const lzma_index *a, const lzma_index *b)
{
    // Compare only the Stream and Block sizes and offsets.
    lzma_index_iter ra, rb;
    lzma_index_iter_init(&ra, a);
    lzma_index_iter_init(&rb, b);

    while (true) {
        bool reta = lzma_index_iter_next(&ra, LZMA_INDEX_ITER_ANY);
        bool retb = lzma_index_iter_next(&rb, LZMA_INDEX_ITER_ANY);
        if (reta)
            return !(reta ^ retb);

        if (ra.stream.number != rb.stream.number
                || ra.stream.block_count
                != rb.stream.block_count
                || ra.stream.compressed_offset
                != rb.stream.compressed_offset
                || ra.stream.uncompressed_offset
                != rb.stream.uncompressed_offset
                || ra.stream.compressed_size
                != rb.stream.compressed_size
                || ra.stream.uncompressed_size
                != rb.stream.uncompressed_size
                || ra.stream.padding
                != rb.stream.padding)
            return false;

        if (ra.stream.block_count == 0)
            continue;

        if (ra.block.number_in_file != rb.block.number_in_file
                || ra.block.compressed_file_offset
                != rb.block.compressed_file_offset
                || ra.block.uncompressed_file_offset
                != rb.block.uncompressed_file_offset
                || ra.block.number_in_stream
                != rb.block.number_in_stream
                || ra.block.compressed_stream_offset
                != rb.block.compressed_stream_offset
                || ra.block.uncompressed_stream_offset
                != rb.block.uncompressed_stream_offset
                || ra.block.uncompressed_size
                != rb.block.uncompressed_size
                || ra.block.unpadded_size
                != rb.block.unpadded_size
                || ra.block.total_size
                != rb.block.total_size)
            return false;
    }
}
コード例 #2
0
ファイル: xz-file.cpp プロジェクト: stbuehler/xz-jni
	bool decodeFillBuffer(std::string &error) {
		for (;0 != strm.avail_out;) {
			LOG_VERBOSE("decodeFillBuffer: %i bytes to go\n", (int) strm.avail_out);

			if (!fill_input_buffer(error)) return false;

			if (0 == strm.avail_in) {
				error.assign("Unexpected end of file");
				return false;
			}

			lzma_ret ret = lzma_code(&strm, LZMA_RUN);
			if (LZMA_OK != ret && LZMA_STREAM_END != ret) {
				errnoLzmaToStr("failed decoding data", ret, error);
				return false;
			}

			if (0 == strm.avail_out) return true; // done filling buffer

			if (LZMA_STREAM_END == ret) {
				if (lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)) {
					error.assign("Unexepected end of file");
					return false;
				}
				/* restart decoder */
				if (!loadBlock(error)) return false;
			}
		}
		return true;
	}
コード例 #3
0
ファイル: xz-file.cpp プロジェクト: stbuehler/xz-jni
	bool decode(std::string &error) {
		assert(0 != strm.avail_out);
		const unsigned char *pos = strm.next_out;

		for (;;) {
			if (!fill_input_buffer(error)) return false;

			if (0 == strm.avail_in) {
				error.assign("Unexpected end of file");
				return false;
			}

			lzma_ret ret = lzma_code(&strm, LZMA_RUN);
			if (LZMA_OK != ret && LZMA_STREAM_END != ret) {
				errnoLzmaToStr("failed decoding data", ret, error);
				return false;
			}

			if (LZMA_STREAM_END == ret && pos == strm.next_out) {
				/* end of stream AND we didn't get new data this round */
				if (lzma_index_iter_next(&iter, LZMA_INDEX_ITER_ANY)) {
					error.assign("Unexepected end of file");
					return false;
				}
				/* restart decoder */
				if (!loadBlock(error)) return false;
			} else {
				return true;
			}
		}
	}
コード例 #4
0
ファイル: read.c プロジェクト: blue119/pixz
static void read_thread(void) {
    off_t offset = ftello(gInFile);
    wanted_t *w = gWantedFiles;
    
    lzma_index_iter iter;
    lzma_index_iter_init(&iter, gIndex);
    while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) {
        // Don't decode the file-index
        off_t boffset = iter.block.compressed_file_offset;
        size_t bsize = iter.block.total_size;
        if (gFileIndexOffset && boffset == gFileIndexOffset)
            continue;
        
        // Do we need this block?
        if (gWantedFiles && gExplicitFiles) {
            off_t uend = iter.block.uncompressed_file_offset +
                iter.block.uncompressed_size;
            if (!w || w->start >= uend) {
                debug("read: skip %llu", iter.block.number_in_file);
                continue;
            }
            for ( ; w && w->end < uend; w = w->next) ;
        }
        debug("read: want %llu", iter.block.number_in_file);
        
        // Seek if needed, and get the data
        if (offset != boffset) {
            fseeko(gInFile, boffset, SEEK_SET);
            offset = boffset;
        }
		
		if (iter.block.uncompressed_size > MAXSPLITSIZE) { // must stream
			if (gRbuf)
				rbuf_consume(gRbuf->insize); // clear
			read_block(true, iter.stream.flags->check,
                iter.block.uncompressed_file_offset);
		} else {
            // Get a block to work with
            pipeline_item_t *pi;
            queue_pop(gPipelineStartQ, (void**)&pi);
            io_block_t *ib = (io_block_t*)(pi->data);
            block_capacity(ib, iter.block.unpadded_size,
                iter.block.uncompressed_size);
            
	        ib->insize = fread(ib->input, 1, bsize, gInFile);
	        if (ib->insize < bsize)
	            die("Error reading block contents");
	        offset += bsize;
	        ib->uoffset = iter.block.uncompressed_file_offset;
			ib->check = iter.stream.flags->check;
			ib->btype = BLOCK_SIZED; // Indexed blocks always sized
			
	        pipeline_split(pi);
		}
    }
    
    pipeline_stop();
}
コード例 #5
0
ファイル: read.c プロジェクト: digideskio/bwa
static void set_block_sizes() {
    lzma_index_iter iter;
    lzma_index_iter_init(&iter, gIndex);
    while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) {
        // exclude the file index block
        lzma_vli off = iter.block.compressed_file_offset;
        if (gFileIndexOffset && off == gFileIndexOffset)
            continue;
        
        size_t in = iter.block.total_size,
            out = iter.block.uncompressed_size;
        if (out > gBlockOutSize)
            gBlockOutSize = out;
        if (in > gBlockInSize)
            gBlockInSize = in;
    }
}
コード例 #6
0
ファイル: test_index.c プロジェクト: Bludge0n/AREsoft
static void
test_read(lzma_index *i)
{
    lzma_index_iter r;
    lzma_index_iter_init(&r, i);

    // Try twice so we see that rewinding works.
    for (size_t j = 0; j < 2; ++j) {
        lzma_vli total_size = 0;
        lzma_vli uncompressed_size = 0;
        lzma_vli stream_offset = LZMA_STREAM_HEADER_SIZE;
        lzma_vli uncompressed_offset = 0;
        uint32_t count = 0;

        while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)) {
            ++count;

            total_size += r.block.total_size;
            uncompressed_size += r.block.uncompressed_size;

            expect(r.block.compressed_file_offset
                   == stream_offset);
            expect(r.block.uncompressed_file_offset
                   == uncompressed_offset);

            stream_offset += r.block.total_size;
            uncompressed_offset += r.block.uncompressed_size;
        }

        expect(lzma_index_total_size(i) == total_size);
        expect(lzma_index_uncompressed_size(i) == uncompressed_size);
        expect(lzma_index_block_count(i) == count);

        lzma_index_iter_rewind(&r);
    }
}
コード例 #7
0
ファイル: read.c プロジェクト: digideskio/bwa
static void wanted_files(size_t count, char **specs) {
    if (!gFileIndexOffset) {
        if (count)
            die("Can't filter non-tarball");
        gWantedFiles = NULL;
        return;
    }
    
    // Remove trailing slashes from specs
    for (char **spec = specs; spec < specs + count; ++spec) {
        char *c = *spec;
        while (*c++) ; // forward to end
        while (--c >= *spec && *c == '/')
            *c = '\0';
    }
    
    bool matched[count];  // for each spec, does it match?
    memset(matched, 0, sizeof(matched));
    wanted_t *last = NULL;
    
    // Check each file in order, to see if we want it
    for (file_index_t *f = gFileIndex; f->name; f = f->next) {
        bool match = !count;
        for (char **spec = specs; spec < specs + count; ++spec) {
            if (spec_match(*spec, f->name)) {
                match = true;
                matched[spec - specs] = true;
                break;
            }
        }
        
        if (match) {
            wanted_t *w = malloc(sizeof(wanted_t));
            *w = (wanted_t){ .name = f->name, .start = f->offset,
                .end = f->next->offset, .next = NULL };
            w->size = w->end - w->start;
            if (last) {
                last->next = w;
            } else {
                gWantedFiles = w;
            }
            last = w;
        }
    }
    
    // Make sure each spec matched
    for (size_t i = 0; i < count; ++i) {
        if (!matched[i])
            die("\"%s\" not found in archive", *(specs + i));
    }
}


#pragma mark THREADS

static void read_thread(void) {
    off_t offset = ftello(gInFile);
    wanted_t *w = gWantedFiles;
    
    lzma_index_iter iter;
    lzma_index_iter_init(&iter, gIndex);
    while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) {
        // Don't decode the file-index
        off_t boffset = iter.block.compressed_file_offset;
        size_t bsize = iter.block.total_size;
        if (gFileIndexOffset && boffset == gFileIndexOffset)
            continue;
        
        // Do we need this block?
        if (gWantedFiles) {
            off_t uend = iter.block.uncompressed_file_offset +
                iter.block.uncompressed_size;
            if (!w || w->start >= uend) {
                debug("read: skip %llu", iter.block.number_in_file);
                continue;
            }
            for ( ; w && w->end < uend; w = w->next) ;
        }
        debug("read: want %llu", iter.block.number_in_file);
        
        // Get a block to work with
        pipeline_item_t *pi;
        queue_pop(gPipelineStartQ, (void**)&pi);
        io_block_t *ib = (io_block_t*)(pi->data);
        
        // Seek if needed, and get the data
        if (offset != boffset) {
            fseeko(gInFile, boffset, SEEK_SET);
            offset = boffset;
        }        
        ib->insize = fread(ib->input, 1, bsize, gInFile);
        if (ib->insize < bsize)
            die("Error reading block contents");
        offset += bsize;
        ib->uoffset = iter.block.uncompressed_file_offset;
        
        pipeline_split(pi);
    }
    
    pipeline_stop();
}
コード例 #8
0
ファイル: list.c プロジェクト: FreeBSDFoundation/freebsd
static bool
print_info_robot(xz_file_info *xfi, file_pair *pair)
{
	char checks[CHECKS_STR_SIZE];
	get_check_names(checks, lzma_index_checks(xfi->idx), false);

	printf("name\t%s\n", pair->src_name);

	printf("file\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64
			"\t%s\t%s\t%" PRIu64 "\n",
			lzma_index_stream_count(xfi->idx),
			lzma_index_block_count(xfi->idx),
			lzma_index_file_size(xfi->idx),
			lzma_index_uncompressed_size(xfi->idx),
			get_ratio(lzma_index_file_size(xfi->idx),
				lzma_index_uncompressed_size(xfi->idx)),
			checks,
			xfi->stream_padding);

	if (message_verbosity_get() >= V_VERBOSE) {
		lzma_index_iter iter;
		lzma_index_iter_init(&iter, xfi->idx);

		while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM))
			printf("stream\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64
				"\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64
				"\t%s\t%s\t%" PRIu64 "\n",
				iter.stream.number,
				iter.stream.block_count,
				iter.stream.compressed_offset,
				iter.stream.uncompressed_offset,
				iter.stream.compressed_size,
				iter.stream.uncompressed_size,
				get_ratio(iter.stream.compressed_size,
					iter.stream.uncompressed_size),
				check_names[iter.stream.flags->check],
				iter.stream.padding);

		lzma_index_iter_rewind(&iter);
		block_header_info bhi;

		while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) {
			if (message_verbosity_get() >= V_DEBUG
					&& parse_details(
						pair, &iter, &bhi, xfi))
				return true;

			printf("block\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64
					"\t%" PRIu64 "\t%" PRIu64
					"\t%" PRIu64 "\t%" PRIu64 "\t%s\t%s",
					iter.stream.number,
					iter.block.number_in_stream,
					iter.block.number_in_file,
					iter.block.compressed_file_offset,
					iter.block.uncompressed_file_offset,
					iter.block.total_size,
					iter.block.uncompressed_size,
					get_ratio(iter.block.total_size,
						iter.block.uncompressed_size),
					check_names[iter.stream.flags->check]);

			if (message_verbosity_get() >= V_DEBUG)
				printf("\t%s\t%" PRIu32 "\t%s\t%" PRIu64
						"\t%" PRIu64 "\t%s",
						check_value,
						bhi.header_size,
						bhi.flags,
						bhi.compressed_size,
						bhi.memusage,
						bhi.filter_chain);

			putchar('\n');
		}
	}

	if (message_verbosity_get() >= V_DEBUG)
		printf("summary\t%" PRIu64 "\t%s\t%" PRIu32 "\n",
				xfi->memusage_max,
				xfi->all_have_sizes ? "yes" : "no",
				xfi->min_version);

	return false;
}
コード例 #9
0
ファイル: list.c プロジェクト: FreeBSDFoundation/freebsd
static bool
print_info_adv(xz_file_info *xfi, file_pair *pair)
{
	// Print the overall information.
	print_adv_helper(lzma_index_stream_count(xfi->idx),
			lzma_index_block_count(xfi->idx),
			lzma_index_file_size(xfi->idx),
			lzma_index_uncompressed_size(xfi->idx),
			lzma_index_checks(xfi->idx),
			xfi->stream_padding);

	// Size of the biggest Check. This is used to calculate the width
	// of the CheckVal field. The table would get insanely wide if
	// we always reserved space for 64-byte Check (128 chars as hex).
	uint32_t check_max = 0;

	// Print information about the Streams.
	//
	// TRANSLATORS: The second line is column headings. All except
	// Check are right aligned; Check is left aligned. Test with
	// "xz -lv foo.xz".
	puts(_("  Streams:\n    Stream    Blocks"
			"      CompOffset    UncompOffset"
			"        CompSize      UncompSize  Ratio"
			"  Check      Padding"));

	lzma_index_iter iter;
	lzma_index_iter_init(&iter, xfi->idx);

	while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_STREAM)) {
		const char *cols1[4] = {
			uint64_to_str(iter.stream.number, 0),
			uint64_to_str(iter.stream.block_count, 1),
			uint64_to_str(iter.stream.compressed_offset, 2),
			uint64_to_str(iter.stream.uncompressed_offset, 3),
		};
		printf("    %*s %*s %*s %*s ",
				tuklib_mbstr_fw(cols1[0], 6), cols1[0],
				tuklib_mbstr_fw(cols1[1], 9), cols1[1],
				tuklib_mbstr_fw(cols1[2], 15), cols1[2],
				tuklib_mbstr_fw(cols1[3], 15), cols1[3]);

		const char *cols2[5] = {
			uint64_to_str(iter.stream.compressed_size, 0),
			uint64_to_str(iter.stream.uncompressed_size, 1),
			get_ratio(iter.stream.compressed_size,
				iter.stream.uncompressed_size),
			_(check_names[iter.stream.flags->check]),
			uint64_to_str(iter.stream.padding, 2),
		};
		printf("%*s %*s  %*s  %-*s %*s\n",
				tuklib_mbstr_fw(cols2[0], 15), cols2[0],
				tuklib_mbstr_fw(cols2[1], 15), cols2[1],
				tuklib_mbstr_fw(cols2[2], 5), cols2[2],
				tuklib_mbstr_fw(cols2[3], 10), cols2[3],
				tuklib_mbstr_fw(cols2[4], 7), cols2[4]);

		// Update the maximum Check size.
		if (lzma_check_size(iter.stream.flags->check) > check_max)
			check_max = lzma_check_size(iter.stream.flags->check);
	}

	// Cache the verbosity level to a local variable.
	const bool detailed = message_verbosity_get() >= V_DEBUG;

	// Information collected from Block Headers
	block_header_info bhi;

	// Print information about the Blocks but only if there is
	// at least one Block.
	if (lzma_index_block_count(xfi->idx) > 0) {
		// Calculate the width of the CheckVal field.
		const int checkval_width = my_max(8, 2 * check_max);

		// TRANSLATORS: The second line is column headings. All
		// except Check are right aligned; Check is left aligned.
		printf(_("  Blocks:\n    Stream     Block"
			"      CompOffset    UncompOffset"
			"       TotalSize      UncompSize  Ratio  Check"));

		if (detailed) {
			// TRANSLATORS: These are additional column headings
			// for the most verbose listing mode. CheckVal
			// (Check value), Flags, and Filters are left aligned.
			// Header (Block Header Size), CompSize, and MemUsage
			// are right aligned. %*s is replaced with 0-120
			// spaces to make the CheckVal column wide enough.
			// Test with "xz -lvv foo.xz".
			printf(_("      CheckVal %*s Header  Flags        "
					"CompSize    MemUsage  Filters"),
					checkval_width - 8, "");
		}

		putchar('\n');

		lzma_index_iter_init(&iter, xfi->idx);

		// Iterate over the Blocks.
		while (!lzma_index_iter_next(&iter, LZMA_INDEX_ITER_BLOCK)) {
			if (detailed && parse_details(pair, &iter, &bhi, xfi))
					return true;

			const char *cols1[4] = {
				uint64_to_str(iter.stream.number, 0),
				uint64_to_str(
					iter.block.number_in_stream, 1),
				uint64_to_str(
					iter.block.compressed_file_offset, 2),
				uint64_to_str(
					iter.block.uncompressed_file_offset, 3)
			};
			printf("    %*s %*s %*s %*s ",
				tuklib_mbstr_fw(cols1[0], 6), cols1[0],
				tuklib_mbstr_fw(cols1[1], 9), cols1[1],
				tuklib_mbstr_fw(cols1[2], 15), cols1[2],
				tuklib_mbstr_fw(cols1[3], 15), cols1[3]);

			const char *cols2[4] = {
				uint64_to_str(iter.block.total_size, 0),
				uint64_to_str(iter.block.uncompressed_size,
						1),
				get_ratio(iter.block.total_size,
					iter.block.uncompressed_size),
				_(check_names[iter.stream.flags->check])
			};
			printf("%*s %*s  %*s  %-*s",
				tuklib_mbstr_fw(cols2[0], 15), cols2[0],
				tuklib_mbstr_fw(cols2[1], 15), cols2[1],
				tuklib_mbstr_fw(cols2[2], 5), cols2[2],
				tuklib_mbstr_fw(cols2[3], detailed ? 11 : 1),
					cols2[3]);

			if (detailed) {
				const lzma_vli compressed_size
						= iter.block.unpadded_size
						- bhi.header_size
						- lzma_check_size(
						iter.stream.flags->check);

				const char *cols3[6] = {
					check_value,
					uint64_to_str(bhi.header_size, 0),
					bhi.flags,
					uint64_to_str(compressed_size, 1),
					uint64_to_str(
						round_up_to_mib(bhi.memusage),
						2),
					bhi.filter_chain
				};
				// Show MiB for memory usage, because it
				// is the only size which is not in bytes.
				printf("%-*s  %*s  %-5s %*s %*s MiB  %s",
					checkval_width, cols3[0],
					tuklib_mbstr_fw(cols3[1], 6), cols3[1],
					cols3[2],
					tuklib_mbstr_fw(cols3[3], 15),
						cols3[3],
					tuklib_mbstr_fw(cols3[4], 7), cols3[4],
					cols3[5]);
			}

			putchar('\n');
		}
	}

	if (detailed) {
		printf(_("  Memory needed:      %s MiB\n"), uint64_to_str(
				round_up_to_mib(xfi->memusage_max), 0));
		printf(_("  Sizes in headers:   %s\n"),
				xfi->all_have_sizes ? _("Yes") : _("No"));
		printf(_("  Minimum XZ Utils version: %s\n"),
				xz_ver_to_str(xfi->min_version));
	}

	return false;
}
コード例 #10
0
ファイル: test_index.c プロジェクト: Bludge0n/AREsoft
static void
test_locate(void)
{
    lzma_index *i = lzma_index_init(NULL);
    expect(i != NULL);
    lzma_index_iter r;
    lzma_index_iter_init(&r, i);

    // Cannot locate anything from an empty Index.
    expect(lzma_index_iter_locate(&r, 0));
    expect(lzma_index_iter_locate(&r, 555));

    // One empty Record: nothing is found since there's no uncompressed
    // data.
    expect(lzma_index_append(i, NULL, 16, 0) == LZMA_OK);
    expect(lzma_index_iter_locate(&r, 0));

    // Non-empty Record and we can find something.
    expect(lzma_index_append(i, NULL, 32, 5) == LZMA_OK);
    expect(!lzma_index_iter_locate(&r, 0));
    expect(r.block.total_size == 32);
    expect(r.block.uncompressed_size == 5);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16);
    expect(r.block.uncompressed_file_offset == 0);

    // Still cannot find anything past the end.
    expect(lzma_index_iter_locate(&r, 5));

    // Add the third Record.
    expect(lzma_index_append(i, NULL, 40, 11) == LZMA_OK);

    expect(!lzma_index_iter_locate(&r, 0));
    expect(r.block.total_size == 32);
    expect(r.block.uncompressed_size == 5);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16);
    expect(r.block.uncompressed_file_offset == 0);

    expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    expect(r.block.total_size == 40);
    expect(r.block.uncompressed_size == 11);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16 + 32);
    expect(r.block.uncompressed_file_offset == 5);

    expect(!lzma_index_iter_locate(&r, 2));
    expect(r.block.total_size == 32);
    expect(r.block.uncompressed_size == 5);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16);
    expect(r.block.uncompressed_file_offset == 0);

    expect(!lzma_index_iter_locate(&r, 5));
    expect(r.block.total_size == 40);
    expect(r.block.uncompressed_size == 11);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16 + 32);
    expect(r.block.uncompressed_file_offset == 5);

    expect(!lzma_index_iter_locate(&r, 5 + 11 - 1));
    expect(r.block.total_size == 40);
    expect(r.block.uncompressed_size == 11);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 16 + 32);
    expect(r.block.uncompressed_file_offset == 5);

    expect(lzma_index_iter_locate(&r, 5 + 11));
    expect(lzma_index_iter_locate(&r, 5 + 15));

    // Large Index
    lzma_index_end(i, NULL);
    i = lzma_index_init(NULL);
    expect(i != NULL);
    lzma_index_iter_init(&r, i);

    for (size_t n = 4; n <= 4 * 5555; n += 4)
        expect(lzma_index_append(i, NULL, n + 8, n) == LZMA_OK);

    expect(lzma_index_block_count(i) == 5555);

    // First Record
    expect(!lzma_index_iter_locate(&r, 0));
    expect(r.block.total_size == 4 + 8);
    expect(r.block.uncompressed_size == 4);
    expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
    expect(r.block.uncompressed_file_offset == 0);

    expect(!lzma_index_iter_locate(&r, 3));
    expect(r.block.total_size == 4 + 8);
    expect(r.block.uncompressed_size == 4);
    expect(r.block.compressed_file_offset == LZMA_STREAM_HEADER_SIZE);
    expect(r.block.uncompressed_file_offset == 0);

    // Second Record
    expect(!lzma_index_iter_locate(&r, 4));
    expect(r.block.total_size == 2 * 4 + 8);
    expect(r.block.uncompressed_size == 2 * 4);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + 4 + 8);
    expect(r.block.uncompressed_file_offset == 4);

    // Last Record
    expect(!lzma_index_iter_locate(
               &r, lzma_index_uncompressed_size(i) - 1));
    expect(r.block.total_size == 4 * 5555 + 8);
    expect(r.block.uncompressed_size == 4 * 5555);
    expect(r.block.compressed_file_offset == lzma_index_total_size(i)
           + LZMA_STREAM_HEADER_SIZE - 4 * 5555 - 8);
    expect(r.block.uncompressed_file_offset
           == lzma_index_uncompressed_size(i) - 4 * 5555);

    // Allocation chunk boundaries. See INDEX_GROUP_SIZE in
    // liblzma/common/index.c.
    const size_t group_multiple = 256 * 4;
    const size_t radius = 8;
    const size_t start = group_multiple - radius;
    lzma_vli ubase = 0;
    lzma_vli tbase = 0;
    size_t n;
    for (n = 1; n < start; ++n) {
        ubase += n * 4;
        tbase += n * 4 + 8;
    }

    while (n < start + 2 * radius) {
        expect(!lzma_index_iter_locate(&r, ubase + n * 4));

        expect(r.block.compressed_file_offset == tbase + n * 4 + 8
               + LZMA_STREAM_HEADER_SIZE);
        expect(r.block.uncompressed_file_offset == ubase + n * 4);

        tbase += n * 4 + 8;
        ubase += n * 4;
        ++n;

        expect(r.block.total_size == n * 4 + 8);
        expect(r.block.uncompressed_size == n * 4);
    }

    // Do it also backwards.
    while (n > start) {
        expect(!lzma_index_iter_locate(&r, ubase + (n - 1) * 4));

        expect(r.block.total_size == n * 4 + 8);
        expect(r.block.uncompressed_size == n * 4);

        --n;
        tbase -= n * 4 + 8;
        ubase -= n * 4;

        expect(r.block.compressed_file_offset == tbase + n * 4 + 8
               + LZMA_STREAM_HEADER_SIZE);
        expect(r.block.uncompressed_file_offset == ubase + n * 4);
    }

    // Test locating in concatenated Index.
    lzma_index_end(i, NULL);
    i = lzma_index_init(NULL);
    expect(i != NULL);
    lzma_index_iter_init(&r, i);
    for (n = 0; n < group_multiple; ++n)
        expect(lzma_index_append(i, NULL, 8, 0) == LZMA_OK);
    expect(lzma_index_append(i, NULL, 16, 1) == LZMA_OK);
    expect(!lzma_index_iter_locate(&r, 0));
    expect(r.block.total_size == 16);
    expect(r.block.uncompressed_size == 1);
    expect(r.block.compressed_file_offset
           == LZMA_STREAM_HEADER_SIZE + group_multiple * 8);
    expect(r.block.uncompressed_file_offset == 0);

    lzma_index_end(i, NULL);
}
コード例 #11
0
ファイル: test_index.c プロジェクト: Bludge0n/AREsoft
static void
test_cat(void)
{
    lzma_index *a, *b, *c;
    lzma_index_iter r;

    // Empty Indexes
    a = create_empty();
    b = create_empty();
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_block_count(a) == 0);
    expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    expect(lzma_index_file_size(a)
           == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8));
    lzma_index_iter_init(&r, a);
    expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));

    b = create_empty();
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_block_count(a) == 0);
    expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    expect(lzma_index_file_size(a)
           == 3 * (2 * LZMA_STREAM_HEADER_SIZE + 8));

    b = create_empty();
    c = create_empty();
    expect(lzma_index_stream_padding(b, 4) == LZMA_OK);
    expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    expect(lzma_index_block_count(b) == 0);
    expect(lzma_index_stream_size(b) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    expect(lzma_index_file_size(b)
           == 2 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4);

    expect(lzma_index_stream_padding(a, 8) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_block_count(a) == 0);
    expect(lzma_index_stream_size(a) == 2 * LZMA_STREAM_HEADER_SIZE + 8);
    expect(lzma_index_file_size(a)
           == 5 * (2 * LZMA_STREAM_HEADER_SIZE + 8) + 4 + 8);

    expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    lzma_index_iter_rewind(&r);
    expect(lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK));
    lzma_index_end(a, NULL);

    // Small Indexes
    a = create_small();
    lzma_vli stream_size = lzma_index_stream_size(a);
    lzma_index_iter_init(&r, a);
    for (int i = SMALL_COUNT; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    b = create_small();
    expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_file_size(a) == stream_size * 2 + 4);
    expect(lzma_index_stream_size(a) > stream_size);
    expect(lzma_index_stream_size(a) < stream_size * 2);
    for (int i = SMALL_COUNT; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    lzma_index_iter_rewind(&r);
    for (int i = SMALL_COUNT * 2; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    b = create_small();
    c = create_small();
    expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
    expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);

    expect(lzma_index_block_count(a) == SMALL_COUNT * 4);
    for (int i = SMALL_COUNT * 2; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    lzma_index_iter_rewind(&r);
    for (int i = SMALL_COUNT * 4; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    lzma_index_end(a, NULL);

    // Mix of empty and small
    a = create_empty();
    b = create_small();
    expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    lzma_index_iter_init(&r, a);
    for (int i = SMALL_COUNT; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    lzma_index_end(a, NULL);

    // Big Indexes
    a = create_big();
    stream_size = lzma_index_stream_size(a);
    b = create_big();
    expect(lzma_index_stream_padding(a, 4) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_file_size(a) == stream_size * 2 + 4);
    expect(lzma_index_stream_size(a) > stream_size);
    expect(lzma_index_stream_size(a) < stream_size * 2);

    b = create_big();
    c = create_big();
    expect(lzma_index_stream_padding(b, 8) == LZMA_OK);
    expect(lzma_index_cat(b, c, NULL) == LZMA_OK);
    expect(lzma_index_stream_padding(a, 12) == LZMA_OK);
    expect(lzma_index_cat(a, b, NULL) == LZMA_OK);
    expect(lzma_index_file_size(a) == stream_size * 4 + 4 + 8 + 12);

    lzma_index_iter_init(&r, a);
    for (int i = BIG_COUNT * 4; i >= 0; --i)
        expect(!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK)
               ^ (i == 0));

    lzma_index_end(a, NULL);
}
コード例 #12
0
ファイル: test_index.c プロジェクト: Bludge0n/AREsoft
static void
test_code(lzma_index *i)
{
    const size_t alloc_size = 128 * 1024;
    uint8_t *buf = malloc(alloc_size);
    expect(buf != NULL);

    // Encode
    lzma_stream strm = LZMA_STREAM_INIT;
    expect(lzma_index_encoder(&strm, i) == LZMA_OK);
    const lzma_vli index_size = lzma_index_size(i);
    succeed(coder_loop(&strm, NULL, 0, buf, index_size,
                       LZMA_STREAM_END, LZMA_RUN));

    // Decode
    lzma_index *d;
    expect(lzma_index_decoder(&strm, &d, MEMLIMIT) == LZMA_OK);
    expect(d == NULL);
    succeed(decoder_loop(&strm, buf, index_size));

    expect(is_equal(i, d));

    lzma_index_end(d, NULL);
    lzma_end(&strm);

    // Decode with hashing
    lzma_index_hash *h = lzma_index_hash_init(NULL, NULL);
    expect(h != NULL);
    lzma_index_iter r;
    lzma_index_iter_init(&r, i);
    while (!lzma_index_iter_next(&r, LZMA_INDEX_ITER_BLOCK))
        expect(lzma_index_hash_append(h, r.block.unpadded_size,
                                      r.block.uncompressed_size) == LZMA_OK);
    size_t pos = 0;
    while (pos < index_size - 1)
        expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
               == LZMA_OK);
    expect(lzma_index_hash_decode(h, buf, &pos, pos + 1)
           == LZMA_STREAM_END);

    lzma_index_hash_end(h, NULL);

    // Encode buffer
    size_t buf_pos = 1;
    expect(lzma_index_buffer_encode(i, buf, &buf_pos, index_size)
           == LZMA_BUF_ERROR);
    expect(buf_pos == 1);

    succeed(lzma_index_buffer_encode(i, buf, &buf_pos, index_size + 1));
    expect(buf_pos == index_size + 1);

    // Decode buffer
    buf_pos = 1;
    uint64_t memlimit = MEMLIMIT;
    expect(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
                                    index_size) == LZMA_DATA_ERROR);
    expect(buf_pos == 1);
    expect(d == NULL);

    succeed(lzma_index_buffer_decode(&d, &memlimit, NULL, buf, &buf_pos,
                                     index_size + 1));
    expect(buf_pos == index_size + 1);
    expect(is_equal(i, d));

    lzma_index_end(d, NULL);

    free(buf);
}