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