📄 scar.java
字号:
* Basically delete all files processed earlier by a scar invocation. * If at the end the top level and enclosing directories are empty, * then they are deleted too. * * @param source File object to be deleted. * @param level 0 if in top level directory. */ private void wipe (File source, int level) { trace(IN, "wipe("+level+")"); if (source.isDirectory()) { if (level == 0 || (level != 0 && recursion)) { // top level or lower level but recursion required String[] entries = source.list(); for (int i = 0; i < entries.length; i++) wipe(new File(source, entries[i]), level + 1); } } try { source.delete(); } catch (Exception ex) { System.err.println(ex.getMessage()); ex.printStackTrace(); } trace(OUT, "wipe("+level+")"); }// ==========================================================================// ScarInputStream inner class.// ========================================================================== // lex tokens for local consumption static final int CONV_WHITE = -1; static final int CONV_PAD = -2; static final int CONV_OTHER = -3; final class ScarInputStream extends FilterInputStream { // Variables and constants //....................................................................... byte[] lineBuffer; // our local buffering buffer! boolean finished; PRZ24 crc; byte[] inBuf = new byte[4]; // Input data buffer byte[] outBuf = new byte[3]; // Output data buffer int inOff; // Bytes in inBuff int outOff; // index into outBuff int outBufMax; // outBuff capacity // Constructor //....................................................................... public ScarInputStream (InputStream is) throws IOException { super(is); trace(IN, "ScarInputStream()"); outBufMax = 3; inOff = outOff = 0; finished = false; crc = new PRZ24(); String line; while (true) { // munge lines until header line is found line = readLine(); if (line == null) throw new EOFException("Missing scar header"); if (line.startsWith("-----" + header + "-----")) break; } while (true) { // munge header lines: version, comments, etc... line = readLine(); if (line == null) throw new EOFException("Missing scar data"); else if (line.length() == 0) break; } trace(OUT, "ScarInputStream()"); } // FilterInputStream methods //....................................................................... public synchronized int read () throws IOException { trace(IN, "ScarInputStream.read()"); if (outOff == 0) { // read another set of 4 bytes if (finished) return -1; // see first if we are at end int inByte = 0; int n = CONV_WHITE; while (n == CONV_WHITE) { // skip whitespace inByte = in.read(); if (inByte < 0) return -1; n = toNumber(inByte); } if (n < 0) { // pad or conv other if (n == CONV_OTHER) // this stream does not contain Base64 data after all throw new CharConversionException(); long computed = crc.getValue(); long actual = 0; crc = null; for (int i = 0; i < 3; i++) { // read checksum bytes inByte = read(); if (inByte < 0) throw new EOFException(); actual = actual << 8 | inByte; } finished = true; outOff = 0; if (actual != computed) throw new IOException("PRZ24 crc mismatch"); return -1; } for (int i = 0; i < 4; ++i) { if (n == CONV_PAD) { if (i < 2) throw new CharConversionException(); } else if (n < 0) // conv char read within a group of 4 throw new CharConversionException(); else inBuf[inOff++] = (byte) n; if (i != 3) { inByte = in.read(); if (inByte < 0) throw new EOFException(); n = toNumber(inByte); } } writeTriplet(); } int b = outBuf[outOff++] & 0xFF; if (outOff == outBufMax) outOff = 0; if (crc != null) crc.update(b); trace(OUT, "ScarInputStream.read()"); return b; } public synchronized int read (byte[] buffer, int offset, int length) throws IOException { trace(IN, "ScarInputStream.read(3)"); debug("ScarInputStream.read("+buffer+", "+offset+", "+length+")"); for (int i = 0; i < length; ++i) { int c = read(); if (c < 0) return (i == 0) ? -1 : i; buffer[offset++] = (byte) c; } trace(OUT, "ScarInputStream.read(3)"); return length; } /** * Override close in Base64InputStream to allow detection of * scar footer line. Basically munge lines until it gets to footer. */ public synchronized void close () throws IOException { trace(IN, "ScarInputStream.close()"); while (true) { String line = readLine(); if (line == null) throw new EOFException("Missing scar footer"); if (line.startsWith("-----" + footer + "-----")) break; } finished = true; outOff = 0; super.close(); trace(OUT, "ScarInputStream.close()"); } // own methods //....................................................................... // source for this method is mainly from SUN's source code. private String readLine () throws IOException { InputStream in = this.in; byte[] buf = lineBuffer; if (buf == null) buf = lineBuffer = new byte[128]; int room = buf.length, offset = 0, c; loop: while (true) { switch (c = in.read()) { case -1: case '\n': break loop; case '\r': int c2 = in.read(); if (c2 != '\n') { if (! (in instanceof PushbackInputStream)) in = this.in = new PushbackInputStream(in); ((PushbackInputStream) in).unread(c2); // push it back } break loop; default: if (--room < 0) { buf = new byte[offset + 128]; room = buf.length - offset - 1; System.arraycopy(lineBuffer, 0, buf, 0, offset); lineBuffer = buf; } buf[offset++] = (byte) c; break; } } if ((c == -1) && (offset == 0)) return null; byte[] lineBytes = new byte[offset]; System.arraycopy(buf, 0, lineBytes, 0, offset); return new String(lineBytes); } private void writeTriplet () { outBufMax = 0; outBuf[outBufMax++] = (byte)(inBuf[0] << 2 | inBuf[1] >>> 4); if (inOff > 2) outBuf[outBufMax++] = (byte)(inBuf[1] << 4 | inBuf[2] >>> 2); if (inOff > 3) outBuf[outBufMax++] = (byte)(inBuf[2] << 6 | inBuf[3]); inOff = 0; } private int toNumber (int b) { if (b >= 'a' & b <= 'z') return b - 'a' + 26; else if (b >= 'A' & b <= 'Z') return b - 'A'; else if (b >= '0' & b <= '9') return b - '0' + 52; else if (b == '+') return 62; else if (b == '/') return 63; else if (b == '=') return CONV_PAD; else if (b == '\n' || b == '\r' || b == ' ' || b == '\t') return CONV_WHITE; else return CONV_OTHER; } } // ScarInputStream// ==========================================================================// ScarOutputStream inner class.// ========================================================================== static final String VERSION = "Version: Alpha.1 --December 97"; static final int MAX_LINE_LENGTH = 64; static final char[] BASE64 = { // 0 1 2 3 4 5 6 7 'A','B','C','D','E','F','G','H', // 0 'I','J','K','L','M','N','O','P', // 1 'Q','R','S','T','U','V','W','X', // 2 'Y','Z','a','b','c','d','e','f', // 3 'g','h','i','j','k','l','m','n', // 4 'o','p','q','r','s','t','u','v', // 5 'w','x','y','z','0','1','2','3', // 6 '4','5','6','7','8','9','+','/' // 7 }; static final char PADDING = '='; final class ScarOutputStream extends FilterOutputStream { PRZ24 crc; byte[] inBuf; // Internal data buffer int inOff; // Bytes in internal data buffer int lineLength; // Number of bytes output so far on line public ScarOutputStream (OutputStream os) throws IOException { super(os); trace(IN, "ScarOutputStream()"); inBuf = new byte[3]; crc = new PRZ24(); inOff = lineLength = 0; out.write(new String("-----" + header + "-----").getBytes()); writeln(); out.write(VERSION.getBytes()); writeln(); if (comment.length() != 0) { out.write(new String("Comment: " + comment).getBytes()); writeln(); } writeln(); trace(OUT, "ScarOutputStream()"); } // FilterOutputStream methods //....................................................................... public void write (int b) throws IOException { inBuf[inOff++] = (byte) b; crc.update(b); if (inOff == 3) writeQuadruplet(); } public void write (byte[] b, int offset, int length) throws IOException { for (int i = 0; i < length; i++) this.write(b[i + offset]); } public void close () throws IOException { trace(IN, "ScarOutputStream.close()"); if (inOff != 0) { // process remaining chars in buffer for (int i = inOff; i < 3; i++) inBuf[i] = 0; writeQuadruplet(); } // force a line break unless the current line is empty if (lineLength != 0) writeln(); out.write(PADDING); int cks = (int) crc.getValue(); inBuf[0] = (byte)(cks >> 16); inBuf[1] = (byte)(cks >> 8); inBuf[2] = (byte) cks; inOff = 3; writeQuadruplet(); writeln(); out.write(new String("-----" + footer + "-----").getBytes()); writeln(); super.flush(); super.close(); trace(OUT, "ScarOutputStream.close()"); } // Own methods //....................................................................... private synchronized void writeQuadruplet () throws IOException { char c = BASE64[(inBuf[0] & 0xFF) >> 2]; out.write(c); c = BASE64[(inBuf[0] & 0x03) << 4 | (inBuf[1] & 0xFF) >> 4]; out.write(c); c = inOff > 1 ? BASE64[(inBuf[1] & 0x0F) << 2 | (inBuf[2] & 0xCF) >> 6] : PADDING; out.write(c); c = inOff > 2 ? BASE64[inBuf[2] & 0x3F] : PADDING; out.write(c); inOff = 0; lineLength += 4; if (lineLength >= MAX_LINE_LENGTH) writeln(); } private void writeln () throws IOException { out.write('\r'); out.write('\n'); lineLength = 0; } } // ScarOutputStream}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -