19 package org.sleuthkit.autopsy.keywordsearch;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.nio.charset.Charset;
39 class AbstractFileStringStream
extends InputStream {
42 private AbstractFile content;
43 private Charset outputCharset;
45 private static final Logger logger = Logger.getLogger(AbstractFileStringStream.class.getName());
46 private static final String NLS = Character.toString((
char) 10);
47 private static final int READ_BUF_SIZE = 256;
48 private long contentOffset = 0;
49 private final byte[] curReadBuf =
new byte[READ_BUF_SIZE];
50 private int bytesInReadBuf = 0;
51 private int readBufOffset = 0;
52 private StringBuilder curString =
new StringBuilder();
53 private int curStringLen = 0;
54 private StringBuilder tempString =
new StringBuilder();
55 private int tempStringLen = 0;
56 private boolean isEOF =
false;
57 private boolean stringAtTempBoundary =
false;
58 private boolean stringAtBufBoundary =
false;
59 private boolean inString =
false;
60 private final byte[] oneCharBuf =
new byte[1];
61 private final int MIN_PRINTABLE_CHARS = 4;
73 public AbstractFileStringStream(AbstractFile content, Charset outputCharset,
boolean preserveOnBuffBoundary) {
74 this.content = content;
75 this.outputCharset = outputCharset;
87 public AbstractFileStringStream(AbstractFile content, Charset outCharset) {
88 this(content, outCharset,
false);
92 public int read(byte[] b,
int off,
int len)
throws IOException {
94 throw new NullPointerException();
95 }
else if (off < 0 || len < 0 || len > b.length - off) {
96 throw new IndexOutOfBoundsException();
97 }
else if (len == 0) {
101 long fileSize = content.getSize();
111 if (stringAtTempBoundary) {
116 stringAtTempBoundary =
false;
120 boolean singleConsecZero =
false;
121 int newCurLen = curStringLen + tempStringLen;
124 while (newCurLen < len) {
126 if (readBufOffset > bytesInReadBuf - 1) {
130 bytesInReadBuf = content.read(curReadBuf, contentOffset, READ_BUF_SIZE);
131 }
catch (TskException ex) {
132 if (curStringLen > 0 || tempStringLen >= MIN_PRINTABLE_CHARS) {
136 int copied = copyToReturn(b, off, len);
142 if (bytesInReadBuf < 1) {
143 if (curStringLen > 0 || tempStringLen >= MIN_PRINTABLE_CHARS) {
147 int copied = copyToReturn(b, off, len);
154 contentOffset += bytesInReadBuf;
159 char c = (char) curReadBuf[readBufOffset++];
160 if (c == 0 && singleConsecZero ==
false) {
162 singleConsecZero =
true;
164 singleConsecZero =
false;
166 if (StringExtract.isPrintableAscii(c)) {
167 tempString.append(c);
169 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
174 }
else if (!singleConsecZero) {
176 if (tempStringLen >= MIN_PRINTABLE_CHARS
177 || stringAtBufBoundary) {
179 tempString.append(NLS);
182 curString.append(tempString);
183 curStringLen += tempStringLen;
185 stringAtBufBoundary =
false;
188 tempString =
new StringBuilder();
192 newCurLen = curStringLen + tempStringLen;
199 stringAtBufBoundary =
true;
205 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
206 if (newCurLen > len) {
207 int appendChars = len - curStringLen;
210 String toAppend = tempString.substring(0, appendChars);
211 String newTemp = tempString.substring(appendChars);
213 curString.append(toAppend);
214 curStringLen += appendChars;
216 tempString =
new StringBuilder(newTemp);
217 tempStringLen = newTemp.length();
219 stringAtTempBoundary =
true;
223 curString.append(tempString);
224 curStringLen += tempStringLen;
227 tempString =
new StringBuilder();
237 final int copied = copyToReturn(b, off, len);
245 private void appendResetTemp() {
246 if (tempStringLen >= MIN_PRINTABLE_CHARS) {
247 curString.append(tempString);
248 curStringLen += tempStringLen;
249 tempString =
new StringBuilder();
256 private int copyToReturn(byte[] b,
int off,
long len) {
258 final String curStringS = curString.toString();
260 byte[] stringBytes = curStringS.getBytes(outputCharset);
261 System.arraycopy(stringBytes, 0, b, off, Math.min(curStringLen, (
int) len));
264 curString =
new StringBuilder();
265 int ret = curStringLen;
272 public int read() throws IOException {
273 final int read = read(oneCharBuf, 0, 1);
275 return oneCharBuf[0];
283 public int available() throws IOException {
289 public long skip(
long n)
throws IOException {
292 return super.skip(n);