annotate lib/mod/src/de/masters_of_disaster/ant/tasks/ar/ArOutputStream.java @ 33:3d86f0391168

Work on improving the build system.
author David Barts <davidb@stashtea.com>
date Fri, 24 Apr 2020 19:45:57 -0700
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
1 package de.masters_of_disaster.ant.tasks.ar;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
2
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
3 import java.io.FilterOutputStream;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
4 import java.io.OutputStream;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
5 import java.io.IOException;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
6
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
7 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
8 * The ArOutputStream writes an ar archive as an OutputStream.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
9 * Methods are provided to put entries, and then write their contents
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
10 * by writing to this stream using write().
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
11 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
12 public class ArOutputStream extends FilterOutputStream {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
13 /** Fail if a long file name is required in the archive or the name contains spaces. */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
14 public static final int LONGFILE_ERROR = 0;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
15
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
16 /** Long paths will be truncated in the archive. Spaces are replaced by '_' */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
17 public static final int LONGFILE_TRUNCATE = 1;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
18
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
19 /** GNU ar variant is used to store long file names and file names with spaced in the archive. */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
20 public static final int LONGFILE_GNU = 2;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
21
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
22 /** BSD ar variant is used to store long file names and file names with spaced in the archive. */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
23 public static final int LONGFILE_BSD = 3;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
24
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
25 protected int currSize;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
26 protected int currBytes;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
27 protected byte[] oneBuf;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
28 protected int longFileMode = LONGFILE_ERROR;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
29 protected boolean writingStarted = false;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
30 protected boolean inEntry = false;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
31
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
32 public ArOutputStream(OutputStream os) throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
33 super(os);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
34 if (null == os) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
35 throw new NullPointerException("os must not be null");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
36 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
37 this.out.write(ArConstants.ARMAGIC,0,ArConstants.ARMAGIC.length);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
38 this.oneBuf = new byte[1];
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
39 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
40
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
41 public void setLongFileMode(int longFileMode) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
42 if (writingStarted) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
43 throw new IllegalStateException("longFileMode cannot be changed after writing to the archive has begun");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
44 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
45 if (LONGFILE_GNU == longFileMode) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
46 throw new UnsupportedOperationException("GNU variant isn't implemented yet");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
47 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
48 if (LONGFILE_BSD == longFileMode) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
49 throw new UnsupportedOperationException("BSD variant isn't implemented yet");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
50 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
51 this.longFileMode = longFileMode;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
52 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
53
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
54 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
55 * Put an entry on the output stream. This writes the entry's
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
56 * header record and positions the output stream for writing
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
57 * the contents of the entry. Once this method is called, the
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
58 * stream is ready for calls to write() to write the entry's
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
59 * contents. Once the contents are written, closeEntry()
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
60 * <B>MUST</B> be called to ensure that all buffered data
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
61 * is completely written to the output stream.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
62 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
63 * @param entry The ArEntry to be written to the archive.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
64 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
65 public void putNextEntry(ArEntry entry) throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
66 writingStarted = true;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
67 if (inEntry) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
68 throw new IOException("the current entry has to be closed before starting a new one");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
69 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
70 String filename = entry.getFilename();
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
71 if ((filename.length() >= ArConstants.NAMELEN)
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
72 && (longFileMode != LONGFILE_TRUNCATE)) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
73 throw new RuntimeException("file name \"" + entry.getFilename()
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
74 + "\" is too long ( > "
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
75 + ArConstants.NAMELEN + " bytes )");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
76 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
77 if (-1 != filename.indexOf(' ')) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
78 if (longFileMode == LONGFILE_TRUNCATE) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
79 entry.setFilename(filename.replace(' ','_'));
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
80 } else {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
81 throw new RuntimeException("file name \"" + entry.getFilename()
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
82 + "\" contains spaces");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
83 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
84 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
85
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
86 byte[] headerBuf = new byte[ArConstants.HEADERLENGTH];
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
87 entry.writeEntryHeader(headerBuf);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
88 this.out.write(headerBuf,0,ArConstants.HEADERLENGTH);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
89
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
90 this.currBytes = 0;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
91 this.currSize = (int) entry.getSize();
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
92 inEntry = true;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
93 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
94
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
95 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
96 * Close an entry. This method MUST be called for all file
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
97 * entries that contain data. The reason is that we must
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
98 * pad an entries data if it is of odd size.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
99 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
100 public void closeEntry() throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
101 if (!inEntry) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
102 throw new IOException("we are not in an entry currently");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
103 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
104
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
105 if (this.currBytes < this.currSize) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
106 throw new IOException("entry closed at '" + this.currBytes
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
107 + "' before the '" + this.currSize
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
108 + "' bytes specified in the header were written");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
109 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
110
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
111 if (1 == (this.currSize & 1)) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
112 this.out.write(ArConstants.PADDING,0,1);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
113 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
114
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
115 inEntry = false;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
116 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
117
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
118 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
119 * Writes a byte to the current ar archive entry.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
120 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
121 * This method simply calls write( byte[], int, int ).
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
122 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
123 * @param b The byte to write to the archive.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
124 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
125 public void write(int b) throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
126 this.oneBuf[0] = (byte) b;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
127 this.write(this.oneBuf, 0, 1);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
128 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
129
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
130 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
131 * Writes bytes to the current ar archive entry.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
132 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
133 * This method simply calls write( byte[], int, int ).
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
134 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
135 * @param wBuf The buffer to write to the archive.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
136 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
137 public void write(byte[] wBuf) throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
138 this.write(wBuf, 0, wBuf.length);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
139 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
140
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
141 /**
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
142 * Writes bytes to the current ar archive entry. This method
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
143 * is aware of the current entry and will throw an exception if
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
144 * you attempt to write bytes past the length specified for the
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
145 * current entry.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
146 *
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
147 * @param wBuf The buffer to write to the archive.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
148 * @param wOffset The offset in the buffer from which to get bytes.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
149 * @param numToWrite The number of bytes to write.
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
150 */
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
151 public void write(byte[] wBuf, int wOffset, int numToWrite) throws IOException {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
152 if (!inEntry) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
153 throw new IOException("we are not in an entry currently");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
154 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
155
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
156 if ((this.currBytes + numToWrite) > this.currSize) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
157 throw new IOException("request to write '" + numToWrite
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
158 + "' bytes exceeds size in header of '"
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
159 + this.currSize + "' bytes");
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
160 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
161
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
162 if (numToWrite > 0) {
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
163 this.out.write(wBuf,wOffset,numToWrite);
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
164 this.currBytes += numToWrite;
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
165 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
166 }
3d86f0391168 Work on improving the build system.
David Barts <davidb@stashtea.com>
parents:
diff changeset
167 }