1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.enforcer.rules.checksum;
20
21 import java.io.FilterReader;
22 import java.io.IOException;
23 import java.io.Reader;
24
25
26
27
28 class NormalizeLineSeparatorReader extends FilterReader {
29
30 private static final int EOL = -1;
31
32
33
34
35 public enum LineSeparator {
36 WINDOWS("\r\n", null),
37 UNIX("\n", '\r');
38
39 private final char[] separatorChars;
40
41 private final Character notPrecededByChar;
42
43 LineSeparator(String separator, Character notPrecededByChar) {
44 separatorChars = separator.toCharArray();
45 this.notPrecededByChar = notPrecededByChar;
46 }
47
48 enum MatchResult {
49 NO_MATCH,
50 POTENTIAL_MATCH,
51 MATCH;
52 }
53
54
55
56
57
58
59
60 public MatchResult matches(char currentCharacter, Character previousCharacter) {
61 int len = separatorChars.length;
62 if (currentCharacter == separatorChars[len - 1]) {
63 if (len > 1) {
64 if (previousCharacter == null || previousCharacter != separatorChars[len - 1]) {
65 return MatchResult.NO_MATCH;
66 }
67 }
68 if (notPrecededByChar != null) {
69 if (previousCharacter != null && notPrecededByChar == previousCharacter) {
70 return MatchResult.NO_MATCH;
71 }
72 }
73 return MatchResult.MATCH;
74 } else if (len > 1 && currentCharacter == separatorChars[len - 2]) {
75 return MatchResult.POTENTIAL_MATCH;
76 }
77 return MatchResult.NO_MATCH;
78 }
79 }
80
81 final LineSeparator lineSeparator;
82
83 Character bufferedCharacter;
84
85 Character previousCharacter;
86
87 NormalizeLineSeparatorReader(Reader reader, LineSeparator lineSeparator) {
88 super(reader);
89 this.lineSeparator = lineSeparator;
90 bufferedCharacter = null;
91 }
92
93 @Override
94 public int read(char[] cbuf, int off, int len) throws IOException {
95 int n;
96 for (n = off; n < off + len; n++) {
97 int readResult = read();
98 if (readResult == EOL) {
99 return n == 0 ? EOL : n;
100 } else {
101 cbuf[n] = (char) readResult;
102 }
103 }
104 return n;
105 }
106
107 @Override
108 public int read() throws IOException {
109
110 if (bufferedCharacter != null) {
111 char localBuffer = bufferedCharacter;
112 bufferedCharacter = null;
113 return localBuffer;
114 }
115 int readResult = super.read();
116 if (readResult == EOL) {
117 return readResult;
118 }
119 char currentCharacter = (char) readResult;
120 if (lineSeparator == LineSeparator.UNIX) {
121 switch (LineSeparator.WINDOWS.matches(currentCharacter, previousCharacter)) {
122 case MATCH:
123 return lineSeparator.separatorChars[0];
124 case POTENTIAL_MATCH:
125 previousCharacter = currentCharacter;
126 return read();
127 default:
128
129 }
130 } else {
131
132 switch (LineSeparator.UNIX.matches(currentCharacter, previousCharacter)) {
133 case MATCH:
134 bufferedCharacter = lineSeparator.separatorChars[1];
135
136 return lineSeparator.separatorChars[0];
137 case POTENTIAL_MATCH:
138
139 throw new IllegalStateException("No potential matches expected for Unix line separator");
140 default:
141
142 }
143 }
144 previousCharacter = currentCharacter;
145 return currentCharacter;
146 }
147 }