1
2
3
4
5
6
7
8
9
10
11
12 package org.eclipse.jgit.util.io;
13
14 import java.io.IOException;
15 import java.io.InputStream;
16
17 import org.eclipse.jgit.diff.RawText;
18
19
20
21
22
23
24
25
26
27 public class AutoCRLFInputStream extends InputStream {
28
29 static final int BUFFER_SIZE = 8096;
30
31 private final byte[] single = new byte[1];
32
33 private final byte[] buf = new byte[BUFFER_SIZE];
34
35 private final InputStream in;
36
37 private int cnt;
38
39 private int ptr;
40
41 private boolean isBinary;
42
43 private boolean detectBinary;
44
45 private byte last;
46
47
48
49
50
51
52
53
54
55
56 public AutoCRLFInputStream(InputStream in, boolean detectBinary) {
57 this.in = in;
58 this.detectBinary = detectBinary;
59 }
60
61
62 @Override
63 public int read() throws IOException {
64 final int read = read(single, 0, 1);
65 return read == 1 ? single[0] & 0xff : -1;
66 }
67
68
69 @Override
70 public int read(byte[] bs, int off, int len) throws IOException {
71 if (len == 0)
72 return 0;
73
74 if (cnt == -1)
75 return -1;
76
77 int i = off;
78 final int end = off + len;
79
80 while (i < end) {
81 if (ptr == cnt && !fillBuffer())
82 break;
83
84 byte b = buf[ptr++];
85 if (isBinary || b != '\n') {
86
87 bs[i++] = last = b;
88 continue;
89 }
90
91 if (b == '\n') {
92 if (last == '\r') {
93 bs[i++] = last = b;
94 continue;
95 }
96 bs[i++] = last = '\r';
97 ptr--;
98 } else
99 bs[i++] = last = b;
100 }
101 int n = i == off ? -1 : i - off;
102 if (n > 0)
103 last = bs[i - 1];
104 return n;
105 }
106
107
108 @Override
109 public void close() throws IOException {
110 in.close();
111 }
112
113 private boolean fillBuffer() throws IOException {
114 cnt = 0;
115 while (cnt < buf.length) {
116 int n = in.read(buf, cnt, buf.length - cnt);
117 if (n < 0) {
118 break;
119 }
120 cnt += n;
121 }
122 if (cnt < 1) {
123 cnt = -1;
124 return false;
125 }
126 if (detectBinary) {
127 isBinary = RawText.isBinary(buf, cnt);
128 detectBinary = false;
129 }
130 ptr = 0;
131 return true;
132 }
133 }