001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020 package org.apache.geronimo.javamail.transport.nntp;
021
022 import java.io.IOException;
023 import java.io.InputStream;
024 import java.io.UnsupportedEncodingException;
025 import java.util.List;
026
027 /**
028 * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
029 */
030 public class StringListInputStream extends InputStream {
031 // the list of lines we're reading from
032 protected List lines;
033
034 // the next line to process.
035 protected int nextLine = 0;
036
037 // current buffer of bytes to read from
038 byte[] buffer;
039
040 // current offset within the buffer;
041 int offset;
042
043 // indicator that we've left off at a split between the CR and LF of a line
044 // break.
045 boolean atLineBreak = false;
046
047 public StringListInputStream(List lines) throws IOException {
048 this.lines = lines;
049 nextLine = 0;
050 buffer = null;
051 offset = 0;
052 atLineBreak = false;
053
054 // if we have at least one line in the list, get the bytes now.
055 if (lines.size() > 0) {
056 nextBuffer();
057 }
058 }
059
060 /**
061 * Just override the single byte read version, which handles all of the
062 * lineend markers correctly.
063 *
064 * @return The next byte from the stream or -1 if we've hit the EOF.
065 */
066 public int read() throws IOException {
067 // leave off at the split between a line?
068 if (atLineBreak) {
069 // flip this off and return the second line end character. Also step
070 // to the next line.
071 atLineBreak = false;
072 nextBuffer();
073 return '\n';
074 }
075 // gone past the end? Got an EOF
076 if (buffer == null) {
077 return -1;
078 }
079
080 // reach the end of the line?
081 if (offset >= buffer.length) {
082 // we're now working on a virtual linebreak
083 atLineBreak = true;
084 return '\r';
085 }
086 // just return the next byte
087 return buffer[offset++];
088
089 }
090
091 /**
092 * Step to the next buffer of string data.
093 *
094 * @exception IOException
095 */
096 protected void nextBuffer() throws IOException {
097 // give an eof check.
098 if (nextLine >= lines.size()) {
099 buffer = null;
100 } else {
101 try {
102 String next = (String) lines.get(nextLine++);
103 buffer = next.getBytes("US-ASCII");
104
105 } catch (UnsupportedEncodingException e) {
106 throw new IOException("Invalid string encoding");
107 }
108 }
109
110 offset = 0;
111 }
112 }