KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonicsystems > jarjar > util > ClassHeaderReader


1 /*
2   Jar Jar Links - A utility to repackage and embed Java libraries
3   Copyright (C) 2004 Tonic Systems, Inc.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; see the file COPYING. if not, write to
17   the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18   Boston, MA 02111-1307 USA
19 */

20
21 package com.tonicsystems.jarjar.util;
22
23 import java.io.*;
24 import java.lang.reflect.Array JavaDoc;
25 import java.util.*;
26
27 public class ClassHeaderReader
28 {
29     private int access;
30     private String JavaDoc thisClass;
31     private String JavaDoc superClass;
32     private String JavaDoc[] interfaces;
33
34     private InputStream in;
35     private byte[] b = new byte[0x2000];
36     private int[] items = new int[1000];
37     private int bsize = 0;
38     private MyByteArrayInputStream bin = new MyByteArrayInputStream();
39     private DataInputStream data = new DataInputStream(bin);
40
41     public int getAccess() {
42         return access;
43     }
44     
45     public String JavaDoc getClassName() {
46         return thisClass;
47     }
48
49     public String JavaDoc getSuperName() {
50         return superClass;
51     }
52
53     public String JavaDoc[] getInterfaces() {
54         return interfaces;
55     }
56
57     public void read(InputStream in) throws IOException {
58         try {
59             this.in = in;
60             bsize = 0;
61             access = 0;
62             thisClass = superClass = null;
63             interfaces = null;
64
65             buffer(10);
66             if (b[0] != (byte)0xCA || b[1] != (byte)0xFE || b[2] != (byte)0xBA || b[3] != (byte)0xBE)
67                 throw new IOException("Bad magic number");
68
69             int minorVersion = readUnsignedShort(4);
70             int majorVersion = readUnsignedShort(6);
71             // TODO: check version
72
int constant_pool_count = readUnsignedShort(8);
73             items = (int[])resizeArray(items, constant_pool_count);
74
75             int index = 10;
76             for (int i = 1; i < constant_pool_count; i++) {
77                 int size;
78                 buffer(index + 3); // TODO: reduce calls to buffer
79
int tag = b[index];
80                 items[i] = index + 1;
81                 switch (tag) {
82                 case 9: // Fieldref
83
case 10: // Methodref
84
case 11: // InterfaceMethodref
85
case 3: // Integer
86
case 4: // Float
87
case 12: // NameAndType
88
size = 4;
89                     break;
90                 case 5: // Long
91
case 6: // Double
92
size = 8;
93                     i++;
94                     break;
95                 case 1: // Utf8
96
size = 2 + readUnsignedShort(index + 1);
97                     break;
98                 case 7: // Class
99
case 8: // String
100
size = 2;
101                     break;
102                 default:
103                     throw new IllegalStateException JavaDoc("Unknown constant pool tag " + tag);
104                 }
105                 index += size + 1;
106             }
107             buffer(index + 8);
108             access = readUnsignedShort(index);
109             thisClass = readClass(index + 2);
110             superClass = readClass(index + 4);
111             int interfaces_count = readUnsignedShort(index + 6);
112         
113             index += 8;
114             buffer(index + interfaces_count * 2);
115             interfaces = new String JavaDoc[interfaces_count];
116             for (int i = 0; i < interfaces_count; i++) {
117                 interfaces[i] = readClass(index);
118                 index += 2;
119             }
120         } finally {
121             in.close();
122         }
123     }
124
125     private String JavaDoc readClass(int index) throws IOException {
126         index = readUnsignedShort(index);
127         if (index == 0)
128             return null;
129         index = readUnsignedShort(items[index]);
130         bin.readFrom(b, items[index]);
131         return data.readUTF();
132     }
133
134     private int readUnsignedShort(int index) {
135         byte[] b = this.b;
136         return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF);
137     }
138
139     private static final int CHUNK = 2048;
140     private void buffer(int amount) throws IOException {
141         if (amount > b.length)
142             b = (byte[])resizeArray(b, b.length * 2);
143         if (amount > bsize) {
144             int rounded = (int)(CHUNK * Math.ceil((float)amount / CHUNK));
145             bsize += read(in, b, bsize, rounded - bsize);
146             if (amount > bsize)
147                 throw new EOFException();
148         }
149     }
150
151     private static int read(InputStream in, byte[] b, int off, int len) throws IOException {
152         int total = 0;
153         while (total < len) {
154             int result = in.read(b, off + total, len - total);
155             if (result == -1)
156                 break;
157             total += result;
158         }
159         return total;
160     }
161
162     private static Object JavaDoc resizeArray(Object JavaDoc array, int length)
163     {
164         if (Array.getLength(array) < length) {
165             Object JavaDoc newArray = Array.newInstance(array.getClass().getComponentType(), length);
166             System.arraycopy(array, 0, newArray, 0, Array.getLength(array));
167             return newArray;
168         } else {
169             return array;
170         }
171     }
172
173     private static class MyByteArrayInputStream extends ByteArrayInputStream
174     {
175         public MyByteArrayInputStream() {
176             super(new byte[0]);
177         }
178
179         public void readFrom(byte[] buf, int pos) {
180             this.buf = buf;
181             this.pos = pos;
182             count = buf.length;
183         }
184     }
185 }
186
Popular Tags