MessageInputStream.java
上传用户:huihesys
上传日期:2007-01-04
资源大小:3877k
文件大小:4k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2.  * MessageInputStream.java
  3.  * Copyright (C) 1999 dog <dog@dog.net.uk>
  4.  * 
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  * 
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  * 
  19.  * You may retrieve the latest version of this library from
  20.  * http://www.dog.net.uk/knife/
  21.  */
  22. package dog.mail.util;
  23. import java.io.*;
  24. /**
  25.  * A utility class for feeding message contents to messages.
  26.  *
  27.  * @author dog@dog.net.uk
  28.  * @version 1.0
  29.  */
  30. public class MessageInputStream extends FilterInputStream {
  31. /**
  32.  * The stream termination octet.
  33.  */
  34. public static final int END = 46;
  35. /**
  36.  * The line termination octet.
  37.  */
  38. public static final int LF = 10;
  39. boolean done = false, debug = false;
  40. int last = -1; // register for the last octet read
  41. int bufsize; // the buffer size for the pushback (CRLF) stream
  42. /**
  43.  * Constructs a message input stream connected to the specified pushback input stream.
  44.  */
  45. public MessageInputStream(PushbackInputStream in) {
  46. super(in);
  47. }
  48. /**
  49.  * Constructs a message input stream connected to the specified pushback input stream.
  50.  */
  51. public MessageInputStream(PushbackInputStream in, boolean debug) {
  52. super(in);
  53. this.debug = debug;
  54. }
  55. /**
  56.  * Reads the next byte of data from this message input stream.
  57.  * Returns -1 if the end of the message stream has been reached.
  58.  * @exception IOException if an I/O error occurs
  59.  */
  60. public int read() throws IOException {
  61. if (done) return -1;
  62. int ch = in.read();
  63. if (ch==END && last==LF) {
  64. int ch2 = in.read(); // look ahead for LF
  65. if (ch2==LF) {
  66. done = true;
  67. return -1; // swallow the END and LF
  68. } else
  69. ((PushbackInputStream)in).unread(ch2);
  70. }
  71. last = ch;
  72. return ch;
  73. }
  74. /**
  75.  * Reads up to b.length bytes of data from this input stream into
  76.  * an array of bytes.
  77.  * Returns -1 if the end of the stream has been reached.
  78.  * @exception IOException if an I/O error occurs
  79.  */
  80. public int read(byte[] b) throws IOException {
  81. return read(b, 0, b.length);
  82. }
  83. /**
  84.  * Reads up to len bytes of data from this input stream into an
  85.  * array of bytes, starting at the specified offset.
  86.  * Returns -1 if the end of the stream has been reached.
  87.  * @exception IOException if an I/O error occurs
  88.  */
  89. public int read(byte[] b, int off, int len) throws IOException {
  90. if (done) return -1;
  91. int l = in.read(b, off, len);
  92. if (debug)
  93. System.err.println("DEBUG: stream: read "+len+" bytes");
  94. int i = indexOfEnd(b, off, l);
  95. if (i>=0) {
  96. ((PushbackInputStream)in).unread(b, i+off+2, (l-(i+2)));
  97. done = true;
  98. return i;
  99. } else if (b[l-1]==LF) {
  100. ((PushbackInputStream)in).unread(b, l-1, 1);
  101. Thread.yield();
  102. return l - 1;
  103. } else if ((l >= 2) && (b[l-2]==LF && b[l-1]==END)) {
  104. ((PushbackInputStream)in).unread(b, l-2, 2);
  105. Thread.yield();
  106. return l - 2;
  107. }
  108. return l;
  109. }
  110. // Discover the index of END in a byte array.
  111. int indexOfEnd(byte[] b, int off, int len) {
  112. for (int i=off+2; i<(off+len); i++)
  113. if (b[i]==LF && b[i-1]==END && b[i-2]==LF)
  114. return i-off-1;
  115. return -1;
  116. }
  117. }