1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.util.io;
11
12 import java.io.EOFException;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.io.StreamCorruptedException;
16 import java.text.MessageFormat;
17
18 import org.eclipse.jgit.internal.JGitText;
19 import org.eclipse.jgit.util.Base85;
20
21
22
23
24
25
26 public class BinaryHunkInputStream extends InputStream {
27
28 private final InputStream in;
29
30 private int lineNumber;
31
32 private byte[] buffer;
33
34 private int pos = 0;
35
36
37
38
39
40
41
42
43 public BinaryHunkInputStream(InputStream in) {
44 this.in = in;
45 }
46
47 @Override
48 public int read() throws IOException {
49 if (pos < 0) {
50 return -1;
51 }
52 if (buffer == null || pos == buffer.length) {
53 fillBuffer();
54 }
55 if (pos >= 0) {
56 return buffer[pos++] & 0xFF;
57 }
58 return -1;
59 }
60
61 @Override
62 public int read(byte[] b, int off, int len) throws IOException {
63 return super.read(b, off, len);
64 }
65
66 @Override
67 public void close() throws IOException {
68 in.close();
69 buffer = null;
70 }
71
72 private void fillBuffer() throws IOException {
73 int length = in.read();
74 if (length < 0) {
75 pos = length;
76 buffer = null;
77 return;
78 }
79 lineNumber++;
80
81 if ('A' <= length && length <= 'Z') {
82 length = length - 'A' + 1;
83 } else if ('a' <= length && length <= 'z') {
84 length = length - 'a' + 27;
85 } else {
86 throw new StreamCorruptedException(MessageFormat.format(
87 JGitText.get().binaryHunkInvalidLength,
88 Integer.valueOf(lineNumber), Integer.toHexString(length)));
89 }
90 byte[] encoded = new byte[Base85.encodedLength(length)];
91 for (int i = 0; i < encoded.length; i++) {
92 int b = in.read();
93 if (b < 0 || b == '\r' || b == '\n') {
94 throw new EOFException(MessageFormat.format(
95 JGitText.get().binaryHunkInvalidLength,
96 Integer.valueOf(lineNumber)));
97 }
98 encoded[i] = (byte) b;
99 }
100
101 int b = in.read();
102 if (b == '\r') {
103
104 b = in.read();
105 }
106 if (b >= 0 && b != '\n') {
107 throw new StreamCorruptedException(MessageFormat.format(
108 JGitText.get().binaryHunkMissingNewline,
109 Integer.valueOf(lineNumber)));
110 }
111 try {
112 buffer = Base85.decode(encoded, length);
113 } catch (IllegalArgumentException e) {
114 StreamCorruptedException ex = new StreamCorruptedException(
115 MessageFormat.format(JGitText.get().binaryHunkDecodeError,
116 Integer.valueOf(lineNumber)));
117 ex.initCause(e);
118 throw ex;
119 }
120 pos = 0;
121 }
122 }