1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.emailcommon.utility; 18 19 import com.android.emailcommon.Logging; 20 import com.android.mail.utils.LogUtils; 21 22 import java.io.FilterInputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 26 /** 27 * Simple class used for debugging only that affords us a view of the raw IMAP or POP3 stream, 28 * in addition to the tokenized version. 29 * 30 * Use of this class *MUST* be restricted to logging-enabled situations only. 31 */ 32 public class LoggingInputStream extends FilterInputStream { 33 private StringBuilder mSb; 34 private boolean mDumpEmptyLines; 35 private final String mTag; 36 37 public LoggingInputStream(InputStream in) { 38 this(in, "RAW", false); 39 } 40 41 public LoggingInputStream(InputStream in, String tag, boolean dumpEmptyLines) { 42 super(in); 43 mTag = tag + " "; 44 mDumpEmptyLines = dumpEmptyLines; 45 initBuffer(); 46 LogUtils.d(Logging.LOG_TAG, mTag + "dump start"); 47 } 48 49 private void initBuffer() { 50 mSb = new StringBuilder(mTag); 51 } 52 53 /** 54 * Collect chars as read, and log them when EOL reached. 55 */ 56 @Override 57 public int read() throws IOException { 58 int oneByte = super.read(); 59 logRaw(oneByte); 60 return oneByte; 61 } 62 63 /** 64 * Collect chars as read, and log them when EOL reached. 65 */ 66 @Override 67 public int read(byte[] b, int offset, int length) throws IOException { 68 int bytesRead = super.read(b, offset, length); 69 int copyBytes = bytesRead; 70 while (copyBytes > 0) { 71 logRaw(b[offset] & 0xFF); 72 copyBytes--; 73 offset++; 74 } 75 76 return bytesRead; 77 } 78 79 /** 80 * Write and clear the buffer 81 */ 82 private void logRaw(int oneByte) { 83 if (oneByte == '\r') { 84 // Don't log. 85 } else if (oneByte == '\n') { 86 flushLog(); 87 } else if (0x20 <= oneByte && oneByte <= 0x7e) { // Printable ASCII. 88 mSb.append((char)oneByte); 89 } else { 90 // email protocols are supposed to be all 7bits, but there are wrong implementations 91 // that do send 8 bit characters... 92 mSb.append("\\x" + Utility.byteToHex(oneByte)); 93 } 94 } 95 96 private void flushLog() { 97 if (mDumpEmptyLines || (mSb.length() > mTag.length())) { 98 LogUtils.d(Logging.LOG_TAG, mSb.toString()); 99 initBuffer(); 100 } 101 } 102 103 @Override 104 public void close() throws IOException { 105 super.close(); 106 flushLog(); 107 } 108 } 109