summaryrefslogtreecommitdiffstats
path: root/depends/lzma/wrapper/lzip_header.c
blob: 398728131383c1580e511518f3c4bf0f528a5c09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "lzip_header.h"

#include <string.h>

#define ELZMA_LZIP_HEADER_SIZE 6
#define ELZMA_LZIP_FOOTER_SIZE 12

static void initLzipHeader(struct elzma_file_header *hdr)
{
	memset((void *)hdr, 0, sizeof(struct elzma_file_header));
}

static int parseLzipHeader(const unsigned char *hdrBuf, struct elzma_file_header *hdr)
{
	if (0 != strncmp("LZIP", (char *)hdrBuf, 4))
		return 1;
	/* XXX: ignore version for now */
	hdr->pb = 2;
	hdr->lp = 0;
	hdr->lc = 3;
	/* unknown at this point */
	hdr->isStreamed = 1;
	hdr->uncompressedSize = 0;
	hdr->dictSize = 1 << (hdrBuf[5] & 0x1F);
	return 0;
}

static int serializeLzipHeader(unsigned char *hdrBuf, const struct elzma_file_header *hdr)
{
	hdrBuf[0] = 'L';
	hdrBuf[1] = 'Z';
	hdrBuf[2] = 'I';
	hdrBuf[3] = 'P';
	hdrBuf[4] = 0;
	{
		int r = 0;
		while ((hdr->dictSize >> r) != 0)
			r++;
		hdrBuf[5] = (unsigned char)(r - 1) & 0x1F;
	}
	return 0;
}

static int serializeLzipFooter(struct elzma_file_footer *ftr, unsigned char *ftrBuf)
{
	unsigned int i = 0;

	/* first crc32 */
	for (i = 0; i < 4; i++)
	{
		*(ftrBuf++) = (unsigned char)(ftr->crc32 >> (i * 8));
	}

	/* next data size */
	for (i = 0; i < 8; i++)
	{
		*(ftrBuf++) = (unsigned char)(ftr->uncompressedSize >> (i * 8));
	}

	/* write version 0 files, omit member length for now*/

	return 0;
}

static int parseLzipFooter(const unsigned char *ftrBuf, struct elzma_file_footer *ftr)
{
	unsigned int i = 0;
	ftr->crc32 = 0;
	ftr->uncompressedSize = 0;

	/* first crc32 */
	for (i = 0; i < 4; i++)
	{
		ftr->crc32 += ((unsigned int)*(ftrBuf++) << (i * 8));
	}

	/* next data size */
	for (i = 0; i < 8; i++)
	{
		ftr->uncompressedSize += (unsigned long long)*(ftrBuf++) << (i * 8);
	}
	/* read version 0 files, omit member length for now*/

	return 0;
}

void initializeLZIPFormatHandler(struct elzma_format_handler *hand)
{
	hand->header_size = ELZMA_LZIP_HEADER_SIZE;
	hand->init_header = initLzipHeader;
	hand->parse_header = parseLzipHeader;
	hand->serialize_header = serializeLzipHeader;
	hand->footer_size = ELZMA_LZIP_FOOTER_SIZE;
	hand->serialize_footer = serializeLzipFooter;
	hand->parse_footer = parseLzipFooter;
}