1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.utils;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23
24
25
26
27 class WindowsLineFeedInputStream extends InputStream {
28
29 private final InputStream target;
30
31 private final boolean ensureLineFeedAtEndOfFile;
32
33 private boolean slashRSeen = false;
34
35 private boolean slashNSeen = false;
36
37 private boolean injectSlashN = false;
38
39 private boolean eofSeen = false;
40
41 WindowsLineFeedInputStream(InputStream in, boolean ensureLineFeedAtEndOfFile) {
42 this.target = in;
43 this.ensureLineFeedAtEndOfFile = ensureLineFeedAtEndOfFile;
44 }
45
46 private int readWithUpdate() throws IOException {
47 final int target = this.target.read();
48 eofSeen = target == -1;
49 if (eofSeen) {
50 return target;
51 }
52 slashRSeen = target == '\r';
53 slashNSeen = target == '\n';
54 return target;
55 }
56
57 @Override
58 public int read() throws IOException {
59 if (eofSeen) {
60 return eofGame();
61 } else if (injectSlashN) {
62 injectSlashN = false;
63 return '\n';
64 } else {
65 boolean prevWasSlashR = slashRSeen;
66 int target = readWithUpdate();
67 if (eofSeen) {
68 return eofGame();
69 }
70 if (target == '\n') {
71 if (!prevWasSlashR) {
72 injectSlashN = true;
73 return '\r';
74 }
75 }
76 return target;
77 }
78 }
79
80 private int eofGame() {
81 if (!ensureLineFeedAtEndOfFile) {
82 return -1;
83 }
84 if (!slashNSeen && !slashRSeen) {
85 slashRSeen = true;
86 return '\r';
87 }
88 if (!slashNSeen) {
89 slashRSeen = false;
90 slashNSeen = true;
91 return '\n';
92 } else {
93 return -1;
94 }
95 }
96
97 @Override
98 public void close() throws IOException {
99 super.close();
100 target.close();
101 }
102
103 @Override
104 public synchronized void mark(int readlimit) {
105 throw new UnsupportedOperationException("Mark not implemented yet");
106 }
107 }