View Javadoc
1 /* 2 * Copyright (C) The Apache Software Foundation. All rights reserved. 3 * 4 * This software is published under the terms of the Apache Software License 5 * version 1.1, a copy of which has been included with this distribution in 6 * the LICENSE file. 7 */ 8 package org.apache.james.util; 9 10 import java.io.IOException; 11 import java.io.InputStream; 12 13 /*** 14 * An InputStream class that terminates the stream when it encounters a 15 * particular byte sequence. 16 * 17 * @version 1.0.0, 24/04/1999 18 * @author Federico Barbieri <scoobie@pop.systemy.it> 19 */ 20 public class CharTerminatedInputStream 21 extends InputStream { 22 23 /*** 24 * The wrapped input stream 25 */ 26 private InputStream in; 27 28 /*** 29 * The terminating character array 30 */ 31 private int match[]; 32 33 /*** 34 * An array containing the last N characters read from the stream, where 35 * N is the length of the terminating character array 36 */ 37 private int buffer[]; 38 39 /*** 40 * The number of bytes that have been read that have not been placed 41 * in the internal buffer. 42 */ 43 private int pos = 0; 44 45 /*** 46 * Whether the terminating sequence has been read from the stream 47 */ 48 private boolean endFound = false; 49 50 /*** 51 * A constructor for this object that takes a stream to be wrapped 52 * and a terminating character sequence. 53 * 54 * @param in the <code>InputStream</code> to be wrapped 55 * @param terminator the array of characters that will terminate the stream. 56 * 57 * @throws IllegalArgumentException if the terminator array is null or empty 58 */ 59 public CharTerminatedInputStream(InputStream in, char[] terminator) { 60 if (terminator == null) { 61 throw new IllegalArgumentException("The terminating character array cannot be null."); 62 } 63 if (terminator.length == 0) { 64 throw new IllegalArgumentException("The terminating character array cannot be of zero length."); 65 } 66 match = new int[terminator.length]; 67 buffer = new int[terminator.length]; 68 for (int i = 0; i < terminator.length; i++) { 69 match[i] = (int)terminator[i]; 70 buffer[i] = (int)terminator[i]; 71 } 72 this.in = in; 73 } 74 75 /*** 76 * Read a byte off this stream. 77 * 78 * @return the byte read off the stream 79 * @throws IOException if an IOException is encountered while reading off the stream 80 */ 81 public int read() throws IOException { 82 if (endFound) { 83 //We've found the match to the terminator 84 return -1; 85 } 86 if (pos == 0) { 87 //We have no data... read in a record 88 int b = in.read(); 89 if (b == -1) { 90 //End of stream reached 91 endFound = true; 92 return -1; 93 } 94 if (b != match[0]) { 95 //this char is not the first char of the match 96 return b; 97 } 98 //this is a match...put this in the first byte of the buffer, 99 // and fall through to matching logic 100 buffer[0] = b; 101 pos++; 102 } else { 103 if (buffer[0] != match[0]) { 104 //Maybe from a previous scan, there is existing data, 105 // and the first available char does not match the 106 // beginning of the terminating string. 107 return topChar(); 108 } 109 //we have a match... fall through to matching logic. 110 } 111 //MATCHING LOGIC 112 113 //The first character is a match... scan for complete match, 114 // reading extra chars as needed, until complete match is found 115 for (int i = 0; i < match.length; i++) { 116 if (i >= pos) { 117 int b = in.read(); 118 if (b == -1) { 119 //end of stream found, so match cannot be fulfilled. 120 // note we don't set endFound, because otherwise 121 // remaining part of buffer won't be returned. 122 return topChar(); 123 } 124 //put the read char in the buffer 125 buffer[pos] = b; 126 pos++; 127 } 128 if (buffer[i] != match[i]) { 129 //we did not find a match... return the top char 130 return topChar(); 131 } 132 } 133 //A complete match was made... 134 endFound = true; 135 return -1; 136 } 137 138 /*** 139 * Private helper method to update the internal buffer of last read characters 140 * 141 * @return the byte that was previously at the front of the internal buffer 142 */ 143 private int topChar() { 144 int b = buffer[0]; 145 if (pos > 1) { 146 //copy down the buffer to keep the fresh data at top 147 System.arraycopy(buffer, 1, buffer, 0, pos - 1); 148 } 149 pos--; 150 return b; 151 } 152 } 153

This page was automatically generated by Maven