19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.Charset;
41 class AbstractFileStringStream
extends InputStream {
44 private AbstractFile content;
45 private Charset outputCharset;
47 private static final Logger logger = Logger.getLogger(AbstractFileStringStream.class.getName());
48 private static final String NLS = Character.toString((
char) 10);
49 private static final int READ_BUF_SIZE = 256;
50 private long contentOffset = 0;
51 private final byte[] curReadBuf =
new byte[READ_BUF_SIZE];
52 private int bytesInReadBuf = 0;
53 private int readBufOffset = 0;
54 private StringBuilder curString =
new StringBuilder();
55 private int curStringLen = 0;
56 private StringBuilder tempString =
new StringBuilder();
57 private int tempStringLen = 0;
58 private boolean isEOF =
false;
59 private boolean stringAtTempBoundary =
false;
60 private boolean stringAtBufBoundary =
false;
61 private boolean inString =
false;
62 private final byte[] oneCharBuf =
new byte[1];
63 private final int MIN_PRINTABLE_CHARS = 4;
76 public AbstractFileStringStream(AbstractFile content, Charset outputCharset,
boolean preserveOnBuffBoundary) {
77 this.content = content;
78 this.outputCharset = outputCharset;
91 public AbstractFileStringStream(AbstractFile content, Charset outCharset) {
92 this(content, outCharset,
false);
96 public int read(byte[] b,
int off,
int len)
throws IOException {
98 throw new NullPointerException();
99 }
else if (off < 0 || len < 0 || len > b.length - off) {
100 throw new IndexOutOfBoundsException();
101 }
else if (len == 0) {
105 long fileSize = content.getSize();
114 if (stringAtTempBoundary) {
119 stringAtTempBoundary =
false;
123 boolean singleConsecZero =
false;
124 int newCurLen = curStringLen + tempStringLen;
126 while (newCurLen < len) {
128 if (readBufOffset > bytesInReadBuf - 1) {
132 bytesInReadBuf = content.read(curReadBuf, contentOffset, READ_BUF_SIZE);
133 }
catch (TskException ex) {
134 if (curStringLen > 0 || tempStringLen >= MIN_PRINTABLE_CHARS) {
138 int copied = copyToReturn(b, off, len);
144 if (bytesInReadBuf < 1) {
145 if (curStringLen > 0 || tempStringLen >= MIN_PRINTABLE_CHARS) {
149 int copied = copyToReturn(b, off, len);
156 contentOffset += bytesInReadBuf;
161 char c = (char) curReadBuf[readBufOffset++];
162 if (c == 0 && singleConsecZero ==
false) {
164 singleConsecZero =
true;
166 singleConsecZero =
false;
168 if (StringExtract.isPrintableAscii(c)) {
169 tempString.append(c);
171 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
176 }
else if (!singleConsecZero) {
178 if (tempStringLen >= MIN_PRINTABLE_CHARS
179 || stringAtBufBoundary) {
181 tempString.append(NLS);
184 curString.append(tempString);
185 curStringLen += tempStringLen;
187 stringAtBufBoundary =
false;
190 tempString =
new StringBuilder();
194 newCurLen = curStringLen + tempStringLen;
201 stringAtBufBoundary =
true;
207 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
208 if (newCurLen > len) {
209 int appendChars = len - curStringLen;
212 String toAppend = tempString.substring(0, appendChars);
213 String newTemp = tempString.substring(appendChars);
215 curString.append(toAppend);
216 curStringLen += appendChars;
218 tempString =
new StringBuilder(newTemp);
219 tempStringLen = newTemp.length();
221 stringAtTempBoundary =
true;
225 curString.append(tempString);
226 curStringLen += tempStringLen;
229 tempString =
new StringBuilder();
239 final int copied = copyToReturn(b, off, len);
247 private void appendResetTemp() {
248 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
249 curString.append(tempString);
250 curStringLen += tempStringLen;
251 tempString =
new StringBuilder();
258 private int copyToReturn(byte[] b,
int off,
long len) {
260 final String curStringS = curString.toString();
262 byte[] stringBytes = curStringS.getBytes(outputCharset);
263 System.arraycopy(stringBytes, 0, b, off, Math.min(curStringLen, (
int) len));
266 curString =
new StringBuilder();
267 int ret = curStringLen;
274 public int read() throws IOException {
275 final int read = read(oneCharBuf, 0, 1);
277 return oneCharBuf[0];
285 public int available() throws IOException {
291 public long skip(
long n)
throws IOException {
294 return super.skip(n);