The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
49813 ripley 1
///////////////////////////////////////////////////////////////////////////////
2
//
3
/// \file       stream_flags_decoder.c
4
/// \brief      Decodes Stream Header and Stream Footer from .xz files
5
//
6
//  Author:     Lasse Collin
7
//
8
//  This file has been put into the public domain.
9
//  You can do whatever you want with this file.
10
//
11
///////////////////////////////////////////////////////////////////////////////
12
 
13
#include "stream_flags_common.h"
14
 
15
 
16
static bool
17
stream_flags_decode(lzma_stream_flags *options, const uint8_t *in)
18
{
19
	// Reserved bits must be unset.
20
	if (in[0] != 0x00 || (in[1] & 0xF0))
21
		return true;
22
 
23
	options->version = 0;
24
	options->check = in[1] & 0x0F;
25
 
26
	return false;
27
}
28
 
29
 
30
extern LZMA_API(lzma_ret)
31
lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in)
32
{
33
	// Magic
34
	if (memcmp(in, lzma_header_magic, sizeof(lzma_header_magic)) != 0)
35
		return LZMA_FORMAT_ERROR;
36
 
37
	// Verify the CRC32 so we can distinguish between corrupt
38
	// and unsupported files.
39
	const uint32_t crc = lzma_crc32(in + sizeof(lzma_header_magic),
40
			LZMA_STREAM_FLAGS_SIZE, 0);
53508 ripley 41
	if (crc != unaligned_read32le(in + sizeof(lzma_header_magic)
49813 ripley 42
			+ LZMA_STREAM_FLAGS_SIZE))
43
		return LZMA_DATA_ERROR;
44
 
45
	// Stream Flags
46
	if (stream_flags_decode(options, in + sizeof(lzma_header_magic)))
47
		return LZMA_OPTIONS_ERROR;
48
 
49
	// Set Backward Size to indicate unknown value. That way
50
	// lzma_stream_flags_compare() can be used to compare Stream Header
51
	// and Stream Footer while keeping it useful also for comparing
52
	// two Stream Footers.
53
	options->backward_size = LZMA_VLI_UNKNOWN;
54
 
55
	return LZMA_OK;
56
}
57
 
58
 
59
extern LZMA_API(lzma_ret)
60
lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in)
61
{
62
	// Magic
63
	if (memcmp(in + sizeof(uint32_t) * 2 + LZMA_STREAM_FLAGS_SIZE,
64
			lzma_footer_magic, sizeof(lzma_footer_magic)) != 0)
65
		return LZMA_FORMAT_ERROR;
66
 
67
	// CRC32
68
	const uint32_t crc = lzma_crc32(in + sizeof(uint32_t),
69
			sizeof(uint32_t) + LZMA_STREAM_FLAGS_SIZE, 0);
53508 ripley 70
	if (crc != unaligned_read32le(in))
49813 ripley 71
		return LZMA_DATA_ERROR;
72
 
73
	// Stream Flags
74
	if (stream_flags_decode(options, in + sizeof(uint32_t) * 2))
75
		return LZMA_OPTIONS_ERROR;
76
 
77
	// Backward Size
53508 ripley 78
	options->backward_size = unaligned_read32le(in + sizeof(uint32_t));
49813 ripley 79
	options->backward_size = (options->backward_size + 1) * 4;
80
 
81
	return LZMA_OK;
82
}