View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.assembly.utils;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  
24  /**
25   * @author Kristian Rosenvold
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 }