001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.pluto.util.assemble.ear;
018:
019: import java.io.FilterOutputStream;
020: import java.io.IOException;
021: import java.io.OutputStream;
022: import java.util.zip.CRC32;
023: import java.util.zip.Checksum;
024:
025: /**
026: * Used as a temporary container for assembled bytes, and for tracking
027: * metadata specific to <code>JarEntry</code> objects, especially the
028: * size of the <code>JarEntry</code> and its checksum.
029: */
030: abstract class AssemblySink extends FilterOutputStream {
031:
032: /**
033: * The default buffer length used when reading and
034: * writing to the sink. By default the value is
035: * 4096 bytes.
036: */
037: protected static int DEFAULT_BUFLEN = 4 * 1024; // 4kb
038:
039: /**
040: * The CRC-32 calculator.
041: */
042: protected final Checksum CRC = new CRC32();
043:
044: /**
045: * The number of bytes written to the sink.
046: */
047: protected long count = 0;
048:
049: /**
050: * Constructs a sink with <i>null</i> as an
051: * underlying output stream.
052: */
053: AssemblySink() {
054: super (null);
055: }
056:
057: /**
058: * Constructs a sink with <i>out</i> as the
059: * underlying output stream. Method calls
060: * on the sink are delegated to the underlying
061: * output stream.
062: *
063: * @param out the underlying output stream.
064: */
065: AssemblySink(OutputStream out) {
066: super (out);
067: }
068:
069: /**
070: * Obtain the number of bytes written to the sink.
071: *
072: * @return the number of bytes written to the sink
073: */
074: long getByteCount() {
075: return count;
076: }
077:
078: /**
079: * Obtain the checksum of the bytes written to
080: * the sink to this point.
081: *
082: * @return the CRC-32 checksum of the bytes in the sink
083: */
084: long getCrc() {
085: return CRC.getValue();
086: }
087:
088: /**
089: * Write out the bytes in the sink to the supplied
090: * output stream, using the default buffer length.
091: *
092: * @param out the OutputStream the sink should be copied to.
093: * @throws IOException
094: */
095: void writeTo(OutputStream out) throws IOException {
096: writeTo(out, DEFAULT_BUFLEN);
097: }
098:
099: /**
100: * Write out the bytes in the sink to the supplied
101: * output stream, using the supplied buffer length.
102: *
103: * @param out the OutputStream the sink should be copied to.
104: * @param buflen the buffer length used when copying bytes
105: * @throws IOException
106: */
107: abstract void writeTo(OutputStream out, int buflen)
108: throws IOException;
109:
110: public synchronized void write(byte[] b) throws IOException {
111: try {
112: out.write(b);
113: count++;
114: CRC.update(b, 0, b.length);
115: } catch (IOException e) {
116: count = 0;
117: CRC.reset();
118: throw e;
119: }
120: }
121:
122: public synchronized void write(byte[] b, int off, int len)
123: throws IOException {
124: try {
125: out.write(b, off, len);
126: count += len;
127: CRC.update(b, off, len);
128: } catch (IOException e) {
129: count = 0;
130: CRC.reset();
131: throw e;
132: }
133: }
134:
135: public synchronized void write(int b) throws IOException {
136: try {
137: out.write(b);
138: count++;
139: CRC.update(b);
140: } catch (IOException e) {
141: count = 0;
142: CRC.reset();
143: throw e;
144: }
145: }
146:
147: /**
148: * Closes the underlying output stream, resets the
149: * checksum calculator, and clears the byte count.
150: */
151: public void close() throws IOException {
152: try {
153: out.close();
154: } finally {
155: CRC.reset();
156: count = 0;
157: }
158: }
159:
160: }
|