package hep.io.xdr; import java.io.DataOutputStream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; /** * A class for writing XDR files. Not too hard to do in Java since the XDR format is very * similar to the Java native DataStream format, except for String and the fact that elements * (or an array of elements) are always padded to a multiple of 4 bytes. * * This class requires the user to call the pad method, to skip to the next * 4-byte boundary after writing an element or array of elements that may not * span a multiple of 4 bytes. * @author Tony Johnson (tonyj@slac.stanford.edu) * @version $Id: XDROutputStream.java 13676 2009-10-20 00:29:18Z tonyj $ */ public class XDROutputStream extends DataOutputStream implements XDRDataOutput { private CountedOutputStream cout; private final static byte[] padding = { 0, 0, 0, 0 }; public XDROutputStream(OutputStream out) { super(new CountedOutputStream(out)); cout = (CountedOutputStream) this.out; } public void writeString(String s) throws IOException { writeInt(s.length()); byte[] ascii = s.getBytes(); write(ascii); pad(); } public void writeStringChars(String s) throws IOException { byte[] ascii = s.getBytes(); write(ascii); pad(); } public void writeIntArray(int[] array) throws IOException { writeInt(array.length); for (int i=0; i<array.length; i++) writeInt(array[i]); } public void writeIntArray(int[] array, int start, int n) throws IOException { writeInt(n); for (int i=start; i<n; i++) writeInt(array[i]); } public void writeDoubleArray(double[] array) throws IOException { writeInt(array.length); for (int i=0; i<array.length; i++) writeDouble(array[i]); } public void writeDoubleArray(double[] array, int start, int n) throws IOException { writeInt(n); for (int i=start; i<n; i++) writeDouble(array[i]); } public void writeFloatArray(float[] array) throws IOException { writeInt(array.length); for (int i=0; i<array.length; i++) writeFloat(array[i]); } public void writeFloatArray(float[] array, int start, int n) throws IOException { writeInt(n); for (int i=start; i<n; i++) writeFloat(array[i]); } /** * Skips appropriate amount to bring stream to 4-byte boundary. */ public void pad() throws IOException { int offset = (int) (getBytesWritten() % 4); if (offset != 0) write(padding,0,4 - offset); } public long getBytesWritten() { return cout.getBytesWritten(); } private static final class CountedOutputStream extends FilterOutputStream { CountedOutputStream(OutputStream out) { super(out); } public void write(int b) throws IOException { out.write(b); count++; } public void write(byte[] data) throws IOException { out.write(data); count += data.length; } public void write(byte[] data, int off, int len) throws IOException { out.write(data,off,len); count += len; } public long getBytesWritten() { return count; } private long count = 0; } }