source: josm/trunk/src/org/tukaani/xz/common/DecoderUtil.java@ 13350

Last change on this file since 13350 was 13350, checked in by stoecker, 6 years ago

see #15816 - add XZ support

File size: 3.7 KB
Line 
1/*
2 * DecoderUtil
3 *
4 * Author: Lasse Collin <lasse.collin@tukaani.org>
5 *
6 * This file has been put into the public domain.
7 * You can do whatever you want with this file.
8 */
9
10package org.tukaani.xz.common;
11
12import java.io.InputStream;
13import java.io.IOException;
14import java.io.EOFException;
15import java.util.zip.CRC32;
16import org.tukaani.xz.XZ;
17import org.tukaani.xz.XZFormatException;
18import org.tukaani.xz.CorruptedInputException;
19import org.tukaani.xz.UnsupportedOptionsException;
20
21public class DecoderUtil extends Util {
22 public static boolean isCRC32Valid(byte[] buf, int off, int len,
23 int ref_off) {
24 CRC32 crc32 = new CRC32();
25 crc32.update(buf, off, len);
26 long value = crc32.getValue();
27
28 for (int i = 0; i < 4; ++i)
29 if ((byte)(value >>> (i * 8)) != buf[ref_off + i])
30 return false;
31
32 return true;
33 }
34
35 public static StreamFlags decodeStreamHeader(byte[] buf)
36 throws IOException {
37 for (int i = 0; i < XZ.HEADER_MAGIC.length; ++i)
38 if (buf[i] != XZ.HEADER_MAGIC[i])
39 throw new XZFormatException();
40
41 if (!isCRC32Valid(buf, XZ.HEADER_MAGIC.length, 2,
42 XZ.HEADER_MAGIC.length + 2))
43 throw new CorruptedInputException("XZ Stream Header is corrupt");
44
45 try {
46 return decodeStreamFlags(buf, XZ.HEADER_MAGIC.length);
47 } catch (UnsupportedOptionsException e) {
48 throw new UnsupportedOptionsException(
49 "Unsupported options in XZ Stream Header");
50 }
51 }
52
53 public static StreamFlags decodeStreamFooter(byte[] buf)
54 throws IOException {
55 if (buf[10] != XZ.FOOTER_MAGIC[0] || buf[11] != XZ.FOOTER_MAGIC[1]) {
56 // NOTE: The exception could be XZFormatException too.
57 // It depends on the situation which one is better.
58 throw new CorruptedInputException("XZ Stream Footer is corrupt");
59 }
60
61 if (!isCRC32Valid(buf, 4, 6, 0))
62 throw new CorruptedInputException("XZ Stream Footer is corrupt");
63
64 StreamFlags streamFlags;
65 try {
66 streamFlags = decodeStreamFlags(buf, 8);
67 } catch (UnsupportedOptionsException e) {
68 throw new UnsupportedOptionsException(
69 "Unsupported options in XZ Stream Footer");
70 }
71
72 streamFlags.backwardSize = 0;
73 for (int i = 0; i < 4; ++i)
74 streamFlags.backwardSize |= (buf[i + 4] & 0xFF) << (i * 8);
75
76 streamFlags.backwardSize = (streamFlags.backwardSize + 1) * 4;
77
78 return streamFlags;
79 }
80
81 private static StreamFlags decodeStreamFlags(byte[] buf, int off)
82 throws UnsupportedOptionsException {
83 if (buf[off] != 0x00 || (buf[off + 1] & 0xFF) >= 0x10)
84 throw new UnsupportedOptionsException();
85
86 StreamFlags streamFlags = new StreamFlags();
87 streamFlags.checkType = buf[off + 1];
88
89 return streamFlags;
90 }
91
92 public static boolean areStreamFlagsEqual(StreamFlags a, StreamFlags b) {
93 // backwardSize is intentionally not compared.
94 return a.checkType == b.checkType;
95 }
96
97 public static long decodeVLI(InputStream in) throws IOException {
98 int b = in.read();
99 if (b == -1)
100 throw new EOFException();
101
102 long num = b & 0x7F;
103 int i = 0;
104
105 while ((b & 0x80) != 0x00) {
106 if (++i >= VLI_SIZE_MAX)
107 throw new CorruptedInputException();
108
109 b = in.read();
110 if (b == -1)
111 throw new EOFException();
112
113 if (b == 0x00)
114 throw new CorruptedInputException();
115
116 num |= (long)(b & 0x7F) << (i * 7);
117 }
118
119 return num;
120 }
121}
Note: See TracBrowser for help on using the repository browser.