source: josm/trunk/src/org/tukaani/xz/UncompressedLZMA2OutputStream.java@ 14807

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

see #15816 - add XZ support

File size: 4.2 KB
Line 
1/*
2 * UncompressedLZMA2OutputStream
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;
11
12import java.io.DataOutputStream;
13import java.io.IOException;
14
15class UncompressedLZMA2OutputStream extends FinishableOutputStream {
16 private final ArrayCache arrayCache;
17
18 private FinishableOutputStream out;
19 private final DataOutputStream outData;
20
21 private final byte[] uncompBuf;
22 private int uncompPos = 0;
23 private boolean dictResetNeeded = true;
24
25 private boolean finished = false;
26 private IOException exception = null;
27
28 private final byte[] tempBuf = new byte[1];
29
30 static int getMemoryUsage() {
31 // uncompBuf + a little extra
32 return 70;
33 }
34
35 UncompressedLZMA2OutputStream(FinishableOutputStream out,
36 ArrayCache arrayCache) {
37 if (out == null)
38 throw new NullPointerException();
39
40 this.out = out;
41 outData = new DataOutputStream(out);
42
43 // We only allocate one array from the cache. We will call
44 // putArray directly in writeEndMarker and thus we don't use
45 // ResettableArrayCache here.
46 this.arrayCache = arrayCache;
47 uncompBuf = arrayCache.getByteArray(
48 LZMA2OutputStream.COMPRESSED_SIZE_MAX, false);
49 }
50
51 public void write(int b) throws IOException {
52 tempBuf[0] = (byte)b;
53 write(tempBuf, 0, 1);
54 }
55
56 public void write(byte[] buf, int off, int len) throws IOException {
57 if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length)
58 throw new IndexOutOfBoundsException();
59
60 if (exception != null)
61 throw exception;
62
63 if (finished)
64 throw new XZIOException("Stream finished or closed");
65
66 try {
67 while (len > 0) {
68 int copySize = Math.min(LZMA2OutputStream.COMPRESSED_SIZE_MAX
69 - uncompPos, len);
70 System.arraycopy(buf, off, uncompBuf, uncompPos, copySize);
71 len -= copySize;
72 uncompPos += copySize;
73
74 if (uncompPos == LZMA2OutputStream.COMPRESSED_SIZE_MAX)
75 writeChunk();
76 }
77 } catch (IOException e) {
78 exception = e;
79 throw e;
80 }
81 }
82
83 private void writeChunk() throws IOException {
84 outData.writeByte(dictResetNeeded ? 0x01 : 0x02);
85 outData.writeShort(uncompPos - 1);
86 outData.write(uncompBuf, 0, uncompPos);
87 uncompPos = 0;
88 dictResetNeeded = false;
89 }
90
91 private void writeEndMarker() throws IOException {
92 if (exception != null)
93 throw exception;
94
95 if (finished)
96 throw new XZIOException("Stream finished or closed");
97
98 try {
99 if (uncompPos > 0)
100 writeChunk();
101
102 out.write(0x00);
103 } catch (IOException e) {
104 exception = e;
105 throw e;
106 }
107
108 finished = true;
109 arrayCache.putArray(uncompBuf);
110 }
111
112 public void flush() throws IOException {
113 if (exception != null)
114 throw exception;
115
116 if (finished)
117 throw new XZIOException("Stream finished or closed");
118
119 try {
120 if (uncompPos > 0)
121 writeChunk();
122
123 out.flush();
124 } catch (IOException e) {
125 exception = e;
126 throw e;
127 }
128 }
129
130 public void finish() throws IOException {
131 if (!finished) {
132 writeEndMarker();
133
134 try {
135 out.finish();
136 } catch (IOException e) {
137 exception = e;
138 throw e;
139 }
140 }
141 }
142
143 public void close() throws IOException {
144 if (out != null) {
145 if (!finished) {
146 try {
147 writeEndMarker();
148 } catch (IOException e) {}
149 }
150
151 try {
152 out.close();
153 } catch (IOException e) {
154 if (exception == null)
155 exception = e;
156 }
157
158 out = null;
159 }
160
161 if (exception != null)
162 throw exception;
163 }
164}
Note: See TracBrowser for help on using the repository browser.