Author: olamy
Date: Mon Oct 27 23:40:02 2014
New Revision: 1634738

URL: http://svn.apache.org/r1634738
Log:
[IO-459] Add WindowsLineEndingInputStream and UnixLineEndingInputStream
Submitted by  Kristian Rosenvold


Added:
    
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
   (with props)
    
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
   (with props)
    
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
   (with props)
    
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
   (with props)

Added: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java?rev=1634738&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
 (added)
+++ 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
 Mon Oct 27 23:40:02 2014
@@ -0,0 +1,110 @@
+package org.apache.commons.io.input;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A filtering input stream that ensures the content will have unix-style line 
endings, LF.
+ * @since 2.5
+ */
+public class UnixLineEndingInputStream
+               extends InputStream {
+
+       private boolean slashNSeen = false;
+
+       private boolean eofSeen = false;
+
+       private final InputStream target;
+
+       private final boolean ensureLineFeedAtEndOfFile;
+
+       /**
+        * Create an input stream that filters another stream
+        *
+        * @param in                        The input stream to wrap
+        * @param ensureLineFeedAtEndOfFile true to ensure that the file ends 
with LF
+        */
+       public UnixLineEndingInputStream(InputStream in, boolean 
ensureLineFeedAtEndOfFile) {
+               this.target = in;
+               this.ensureLineFeedAtEndOfFile = ensureLineFeedAtEndOfFile;
+       }
+
+       private int readWithUpdate() throws IOException {
+               final int target = this.target.read();
+               eofSeen = target == -1;
+               if (eofSeen) {
+                       return target;
+               }
+               slashNSeen = target == '\n';
+               return target;
+       }
+
+       /**
+        * @inheritDoc
+        */
+
+       @Override public int read()
+                       throws IOException {
+               if (eofSeen) {
+                       return eofGame();
+               } else {
+                       int target = readWithUpdate();
+                       if (eofSeen) {
+                               return eofGame();
+                       }
+                       if (target == '\r') {
+                               target = readWithUpdate();
+                       }
+                       return target;
+               }
+       }
+
+       private int eofGame() {
+               if (!ensureLineFeedAtEndOfFile) {
+                       return -1;
+               }
+               if (!slashNSeen) {
+                       slashNSeen = true;
+                       return '\n';
+               } else {
+                       return -1;
+               }
+       }
+
+       /**
+        * Closes the stream. Also closes the underlying stream.
+        */
+       @Override
+       public void close()
+                       throws IOException {
+               super.close();
+               target.close();
+       }
+
+       /**
+        * @inheritDoc
+        */
+       @Override
+       public synchronized void mark(int readlimit) {
+               throw new UnsupportedOperationException("Mark notsupported");
+       }
+}

Propchange: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/UnixLineEndingInputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java?rev=1634738&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
 (added)
+++ 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
 Mon Oct 27 23:40:02 2014
@@ -0,0 +1,123 @@
+package org.apache.commons.io.input;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A filtering input stream that ensures the content will have windows line 
endings, CRLF.
+ */
+public class WindowsLineEndingInputStream
+               extends InputStream {
+
+       private boolean slashRSeen = false;
+
+       private boolean slashNSeen = false;
+
+       private boolean injectSlashN = false;
+
+       private boolean eofSeen = false;
+
+       private final InputStream target;
+
+       private final boolean ensureLineFeedAtEndOfFile;
+
+       /**
+        * Create an input stream that filters another stream
+        *
+        * @param in                        The input stream to wrap
+        * @param ensureLineFeedAtEndOfFile true to ensure that the file ends 
with CRLF
+        */
+       public WindowsLineEndingInputStream(InputStream in, boolean 
ensureLineFeedAtEndOfFile) {
+               this.target = in;
+               this.ensureLineFeedAtEndOfFile = ensureLineFeedAtEndOfFile;
+       }
+
+       private int readWithUpdate() throws IOException {
+               final int target = this.target.read();
+               eofSeen = target == -1;
+               if (eofSeen) {
+                       return target;
+               }
+               slashRSeen = target == '\r';
+               slashNSeen = target == '\n';
+               return target;
+       }
+
+       /**
+        * @inheritDoc
+        */
+       @Override
+       public int read() throws IOException {
+               if (eofSeen) {
+                       return eofGame();
+               } else if (injectSlashN) {
+                       injectSlashN = false;
+                       return '\n';
+               } else {
+                       boolean prevWasSlashR = slashRSeen;
+                       int target = readWithUpdate();
+                       if (eofSeen) {
+                               return eofGame();
+                       }
+                       if (target == '\n') {
+                               if (!prevWasSlashR) {
+                                       injectSlashN = true;
+                                       return '\r';
+                               }
+                       }
+                       return target;
+               }
+       }
+
+       private int eofGame() {
+               if (!ensureLineFeedAtEndOfFile) {
+                       return -1;
+               }
+               if (!slashNSeen && !slashRSeen) {
+                       slashRSeen = true;
+                       return '\r';
+               }
+               if (!slashNSeen) {
+                       slashRSeen = false;
+                       slashNSeen = true;
+                       return '\n';
+               } else {
+                       return -1;
+               }
+       }
+
+       /**
+        * Closes the stream. Also closes the underlying stream.
+        */
+       @Override
+       public void close() throws IOException {
+               super.close();
+               target.close();
+       }
+
+       /**
+        * @inheritDoc
+        */
+       @Override public synchronized void mark(int readlimit) {
+               throw new UnsupportedOperationException("Mark not supported");
+       }
+}

Propchange: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/main/java/org/apache/commons/io/input/WindowsLineEndingInputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java?rev=1634738&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
 (added)
+++ 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
 Mon Oct 27 23:40:02 2014
@@ -0,0 +1,55 @@
+package org.apache.commons.io.input;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class UnixLineEndingInputStreamTest {
+
+       @Test
+       public void simpleString() throws Exception {
+               assertEquals("abc\n", roundtrip("abc"));
+       }
+
+       @Test
+       public void inTheMiddleOfTheLine() throws Exception {
+               assertEquals("a\nbc\n", roundtrip("a\r\nbc"));
+       }
+
+       @Test
+       public void multipleBlankLines() throws Exception {
+               assertEquals("a\n\nbc\n", roundtrip("a\r\n\r\nbc"));
+       }
+
+       @Test
+       public void twoLinesAtEnd() throws Exception {
+               assertEquals("a\n\n", roundtrip("a\r\n\r\n"));
+       }
+
+       @Test
+       public void malformed() throws Exception {
+               assertEquals("abc", roundtrip("a\rbc", false));
+       }
+
+       @Test
+       public void retainLineFeed() throws Exception {
+               assertEquals("a\n\n", roundtrip("a\r\n\r\n", false));
+               assertEquals("a", roundtrip("a", false));
+       }
+
+       private String roundtrip(String msg) throws IOException {
+               return roundtrip(msg, true);
+       }
+
+       private String roundtrip(String msg, boolean ensure) throws IOException 
{
+               ByteArrayInputStream baos = new 
ByteArrayInputStream(msg.getBytes("UTF-8"));
+               UnixLineEndingInputStream lf = new 
UnixLineEndingInputStream(baos, ensure);
+               byte[] buf = new byte[100];
+               final int read = lf.read(buf);
+               return new String(buf, 0, read, "UTF-8");
+       }
+
+}
\ No newline at end of file

Propchange: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/UnixLineEndingInputStreamTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java?rev=1634738&view=auto
==============================================================================
--- 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
 (added)
+++ 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
 Mon Oct 27 23:40:02 2014
@@ -0,0 +1,78 @@
+package org.apache.commons.io.input;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.junit.Test;
+
+public class WindowsLineEndingInputStreamTest {
+       @Test
+       public void simpleString() throws Exception {
+               assertEquals("abc\r\n", roundtrip("abc"));
+       }
+
+       @Test
+       public void inTheMiddleOfTheLine() throws Exception {
+               assertEquals("a\r\nbc\r\n", roundtrip("a\r\nbc"));
+       }
+
+       @Test
+       public void multipleBlankLines() throws Exception {
+               assertEquals("a\r\n\r\nbc\r\n", roundtrip("a\r\n\r\nbc"));
+       }
+
+       @Test
+       public void twoLinesAtEnd() throws Exception {
+               assertEquals("a\r\n\r\n", roundtrip("a\r\n\r\n"));
+       }
+
+       @Test
+       public void linuxLinefeeds() throws Exception {
+               final String roundtrip = roundtrip("ab\nc", false);
+               assertEquals("ab\r\nc", roundtrip);
+       }
+
+
+       @Test
+       public void malformed() throws Exception {
+               assertEquals("a\rbc", roundtrip("a\rbc", false));
+       }
+
+       @Test
+       public void retainLineFeed() throws Exception {
+               assertEquals("a\r\n\r\n", roundtrip("a\r\n\r\n", false));
+               assertEquals("a", roundtrip("a", false));
+       }
+
+       private String roundtrip(String msg) throws IOException {
+               return roundtrip(msg, true);
+       }
+
+       private String roundtrip(String msg, boolean ensure) throws IOException 
{
+               ByteArrayInputStream baos = new 
ByteArrayInputStream(msg.getBytes("UTF-8"));
+               WindowsLineEndingInputStream lf = new 
WindowsLineEndingInputStream(baos, ensure);
+               byte[] buf = new byte[100];
+               final int read = lf.read(buf);
+               return new String(buf, 0, read, "UTF-8");
+       }
+}
\ No newline at end of file

Propchange: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/io/trunk/src/test/java/org/apache/commons/io/input/WindowsLineEndingInputStreamTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision


Reply via email to