View Javadoc
1   package org.apache.maven.plugins.assembly.utils;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  
25  /**
26   * @author Kristian Rosenvold
27   */
28  class WindowsLineFeedInputStream
29      extends InputStream
30  {
31  
32      private final InputStream target;
33  
34      private final boolean ensureLineFeedAtEndOfFile;
35  
36      private boolean slashRSeen = false;
37  
38      private boolean slashNSeen = false;
39  
40      private boolean injectSlashN = false;
41  
42      private boolean eofSeen = false;
43  
44      public WindowsLineFeedInputStream( InputStream in, boolean ensureLineFeedAtEndOfFile )
45      {
46          this.target = in;
47          this.ensureLineFeedAtEndOfFile = ensureLineFeedAtEndOfFile;
48      }
49  
50      private int readWithUpdate()
51          throws IOException
52      {
53          final int target = this.target.read();
54          eofSeen = target == -1;
55          if ( eofSeen )
56          {
57              return target;
58          }
59          slashRSeen = target == '\r';
60          slashNSeen = target == '\n';
61          return target;
62      }
63  
64      @Override
65      public int read()
66          throws IOException
67      {
68          if ( eofSeen )
69          {
70              return eofGame();
71          }
72          else if ( injectSlashN )
73          {
74              injectSlashN = false;
75              return '\n';
76          }
77          else
78          {
79              boolean prevWasSlashR = slashRSeen;
80              int target = readWithUpdate();
81              if ( eofSeen )
82              {
83                  return eofGame();
84              }
85              if ( target == '\n' )
86              {
87                  if ( !prevWasSlashR )
88                  {
89                      injectSlashN = true;
90                      return '\r';
91                  }
92              }
93              return target;
94          }
95      }
96  
97      private int eofGame()
98      {
99          if ( !ensureLineFeedAtEndOfFile )
100         {
101             return -1;
102         }
103         if ( !slashNSeen && !slashRSeen )
104         {
105             slashRSeen = true;
106             return '\r';
107         }
108         if ( !slashNSeen )
109         {
110             slashRSeen = false;
111             slashNSeen = true;
112             return '\n';
113         }
114         else
115         {
116             return -1;
117         }
118     }
119 
120     @Override
121     public void close()
122         throws IOException
123     {
124         super.close();
125         target.close();
126     }
127 
128     @Override
129     public synchronized void mark( int readlimit )
130     {
131         throw new UnsupportedOperationException( "Mark not implemented yet" );
132     }
133 }