1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.vafer.jdeb.ar;
17
18 import java.io.IOException;
19 import java.io.OutputStream;
20
21
22
23
24
25
26 public class ArOutputStream extends OutputStream implements ArConstants {
27
28 private final OutputStream out;
29 private long archiveOffset = 0;
30 private long entryOffset = 0;
31 private ArEntry prevEntry;
32
33 public ArOutputStream( final OutputStream pOut ) {
34 out = pOut;
35 }
36
37 private long writeArchiveHeader() throws IOException {
38 out.write(HEADER);
39 return HEADER.length;
40 }
41
42 private void closeEntry() throws IOException {
43 if ((entryOffset % 2) != 0) {
44 write('\n');
45 archiveOffset++;
46 }
47 }
48
49 public void putNextEntry( final ArEntry pEntry ) throws IOException {
50
51 if (prevEntry == null) {
52 archiveOffset += writeArchiveHeader();
53 } else {
54 if (prevEntry.getLength() != entryOffset) {
55 throw new IOException("length does not match entry (" + prevEntry.getLength() + " != " + entryOffset);
56 }
57
58 closeEntry();
59 }
60
61 prevEntry = pEntry;
62
63 archiveOffset += writeEntryHeader(pEntry);
64
65 entryOffset = 0;
66 }
67
68
69
70
71
72
73
74
75
76 private void write(String data, int size, String fieldname) throws IOException {
77 if (data.length() > size) {
78 throw new IOException(fieldname + " too long");
79 }
80
81 long length = size - write(data);
82 for (int i = 0; i < length; i++) {
83 write(' ');
84 }
85 }
86
87 private long write( final String data ) throws IOException {
88 final byte[] bytes = data.getBytes("ascii");
89 write(bytes);
90 return bytes.length;
91 }
92
93 private long writeEntryHeader( final ArEntry entry ) throws IOException {
94
95 String n = entry.getName();
96 write(n, FIELD_SIZE_NAME, "filename");
97
98 String m = "" + (entry.getLastModified() / 1000);
99 write(m, FIELD_SIZE_LASTMODIFIED, "lastmodified");
100
101 String u = "" + entry.getUserId();
102 write(u, FIELD_SIZE_UID, "userid");
103
104 String g = "" + entry.getGroupId();
105 write(g, FIELD_SIZE_GID, "groupid");
106
107 String fm = Integer.toString(entry.getMode(), 8);
108 write(fm, FIELD_SIZE_MODE, "filemode");
109
110 String s = "" + entry.getLength();
111 write(s, FIELD_SIZE_LENGTH, "size");
112
113 write(ENTRY_TERMINATOR);
114
115 return HEADER_SIZE;
116 }
117
118 public void write(int b) throws IOException {
119 out.write(b);
120 entryOffset++;
121 }
122
123 public void write(byte[] b, int off, int len) throws IOException {
124 out.write(b, off, len);
125 entryOffset += len;
126 }
127
128 public void write(byte[] b) throws IOException {
129 out.write(b);
130 entryOffset += b.length;
131 }
132
133 public void close() throws IOException {
134 closeEntry();
135 out.close();
136 prevEntry = null;
137 }
138
139 }