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.InputStream;
20
21
22
23
24
25
26 public class ArInputStream extends InputStream implements ArConstants {
27
28 private final InputStream input;
29 private long offset = 0;
30
31 public ArInputStream( final InputStream pInput ) {
32 input = pInput;
33 }
34
35 public ArEntry getNextEntry() throws IOException {
36
37 if (offset == 0) {
38 final byte[] expected = HEADER;
39 final byte[] realized = new byte[expected.length];
40 final int read = input.read(realized);
41 if (read != expected.length) {
42 throw new IOException("failed to read header");
43 }
44 for (int i = 0; i < expected.length; i++) {
45 if (expected[i] != realized[i]) {
46 throw new IOException("invalid header " + new String(realized));
47 }
48 }
49 }
50
51 if (input.available() == 0) {
52 return null;
53 }
54
55 if (offset % 2 != 0) {
56 read();
57 }
58
59 final byte[] name = new byte[FIELD_SIZE_NAME];
60 final byte[] lastmodified = new byte[FIELD_SIZE_LASTMODIFIED];
61 final byte[] userid = new byte[FIELD_SIZE_UID];
62 final byte[] groupid = new byte[FIELD_SIZE_GID];
63 final byte[] filemode = new byte[FIELD_SIZE_MODE];
64 final byte[] length = new byte[FIELD_SIZE_LENGTH];
65
66 read(name);
67 read(lastmodified);
68 read(userid);
69 read(groupid);
70 read(filemode);
71 read(length);
72
73 final byte[] expected = ENTRY_TERMINATOR;
74 final byte[] realized = new byte[expected.length];
75 final int read = input.read(realized);
76 if (read != expected.length) {
77 throw new IOException("failed to read entry header");
78 }
79 for (int i = 0; i < expected.length; i++) {
80 if (expected[i] != realized[i]) {
81 throw new IOException("invalid entry header. not read the content?");
82 }
83 }
84
85 return new ArEntry(new String(name).trim(), Long.parseLong(new String(length).trim()));
86 }
87
88
89 public int read() throws IOException {
90 final int ret = input.read();
91 offset++;
92 return ret;
93 }
94
95 public void close() throws IOException {
96 input.close();
97 super.close();
98 }
99
100 }