| CLCPInfo.java |
1 // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2
3 package jminusminus;
4
5 import java.io.DataOutputStream;
6 import java.io.IOException;
7
8 import static jminusminus.CLConstants.*;
9
10 /**
11 * Representation of cp_info structure.
12 */
13 abstract class CLCPInfo {
14 /**
15 * Index of this object in the constant pool.
16 */
17 public int cpIndex;
18
19 /**
20 * cp_info.tag item.
21 */
22 public short tag;
23
24 /**
25 * Writes the contents of this constant pool item to the specified output stream.
26 *
27 * @param out output stream.
28 * @throws IOException if an error occurs while writing.
29 */
30 public void write(CLOutputStream out) throws IOException {
31 out.writeByte(tag);
32 }
33
34 /**
35 * Return true if this CLCPInfo object is the same as other, and false otherwise.
36 *
37 * @param other the reference CLCPInfo object with which to compare.
38 * @return true if this CLCPInfo object is the same as other, and false otherwise.
39 */
40 public boolean equals(Object other) {
41 return false;
42 }
43 }
44
45 /**
46 * Representation of CONSTANT_Class_info structure.
47 */
48 class CLConstantClassInfo extends CLCPInfo {
49 /**
50 * CONSTANT_Class_info.name_index item.
51 */
52 public int nameIndex;
53
54 /**
55 * Constructs a CLConstantClassInfo object.
56 *
57 * @param nameIndex CONSTANT_Class_info.name_index item.
58 */
59 public CLConstantClassInfo(int nameIndex) {
60 super.tag = CONSTANT_Class;
61 this.nameIndex = nameIndex;
62 }
63
64 /**
65 * {@inheritDoc}
66 */
67 public void write(CLOutputStream out) throws IOException {
68 super.write(out);
69 out.writeShort(nameIndex);
70 }
71
72 /**
73 * {@inheritDoc}
74 */
75 public boolean equals(Object other) {
76 if (other instanceof CLConstantClassInfo) {
77 CLConstantClassInfo c = (CLConstantClassInfo) other;
78 if (c.nameIndex == nameIndex) {
79 return true;
80 }
81 }
82 return false;
83 }
84 }
85
86 /**
87 * Abstract super class of CONSTANT_Fieldref_info, CONSTANT_Methodref_info,
88 * CONSTANT_InterfaceMethodref_info structures.
89 */
90 abstract class CLConstantMemberRefInfo extends CLCPInfo {
91 /**
92 * CONSTANT_Memberref_info.class_index item.
93 */
94 public int classIndex;
95
96 /**
97 * CONSTANT_Memberref_info.name_and_type_index item.
98 */
99 public int nameAndTypeIndex;
100
101 /**
102 * Constructs a CLConstantMemberRefInfo object.
103 *
104 * @param classIndex CONSTANT_Memberref_info.class_index item.
105 * @param nameAndTypeIndex CONSTANT_Memberref_info.name_and_type_index item.
106 * @param tag CONSTANT_Memberref_info.tag item.
107 */
108 protected CLConstantMemberRefInfo(int classIndex, int nameAndTypeIndex, short tag) {
109 super.tag = tag;
110 this.classIndex = classIndex;
111 this.nameAndTypeIndex = nameAndTypeIndex;
112 }
113
114 /**
115 * {@inheritDoc}
116 */
117 public void write(CLOutputStream out) throws IOException {
118 super.write(out);
119 out.writeShort(classIndex);
120 out.writeShort(nameAndTypeIndex);
121 }
122
123 /**
124 * {@inheritDoc}
125 */
126 public boolean equals(Object other) {
127 if (other instanceof CLConstantMemberRefInfo) {
128 CLConstantMemberRefInfo c = (CLConstantMemberRefInfo) other;
129 if ((c.tag == tag) && (c.classIndex == classIndex)
130 && (c.nameAndTypeIndex == nameAndTypeIndex)) {
131 return true;
132 }
133 }
134 return false;
135 }
136 }
137
138 /**
139 * Representation of CONSTANT_Fieldref_info structure.
140 */
141 class CLConstantFieldRefInfo extends CLConstantMemberRefInfo {
142 /**
143 * Constructs a CLConstantFieldRefInfo object.
144 *
145 * @param classIndex CONSTANT_Fieldref_info.class_index item.
146 * @param nameAndTypeIndex CONSTANT_Fieldref_info.name_and_type_index item.
147 */
148
149 public CLConstantFieldRefInfo(int classIndex, int nameAndTypeIndex) {
150 super(classIndex, nameAndTypeIndex, CONSTANT_Fieldref);
151 }
152 }
153
154 /**
155 * Representation of CONSTANT_Methodref_info structure.
156 */
157 class CLConstantMethodRefInfo extends CLConstantMemberRefInfo {
158 /**
159 * Constructs a CLConstantMethodRefInfo object.
160 *
161 * @param classIndex CONSTANT_Methodref_info.class_index item.
162 * @param nameAndTypeIndex CONSTANT_Methodref_info.name_and_type_index item.
163 */
164 public CLConstantMethodRefInfo(int classIndex, int nameAndTypeIndex) {
165 super(classIndex, nameAndTypeIndex, CONSTANT_Methodref);
166 }
167 }
168
169 /**
170 * Representation of CONSTANT_InterfaceMethodref_info structure.
171 */
172 class CLConstantInterfaceMethodRefInfo extends CLConstantMemberRefInfo {
173 /**
174 * Constructs a CLConstantInterfaceMethodRefInfo object.
175 *
176 * @param classIndex CONSTANT_InterfaceMethodref_info.class_index item.
177 * @param nameAndTypeIndex CONSTANT_InterfaceMethodref_info.name_and_type_index item.
178 */
179 public CLConstantInterfaceMethodRefInfo(int classIndex, int nameAndTypeIndex) {
180 super(classIndex, nameAndTypeIndex, CONSTANT_InterfaceMethodref);
181 }
182 }
183
184 /**
185 * Representation of CONSTANT_String_info structure.
186 */
187 class CLConstantStringInfo extends CLCPInfo {
188 /**
189 * CONSTANT_String_info.string_index item.
190 */
191 public int stringIndex;
192
193 /**
194 * Constructs a CLConstantStringInfo object.
195 *
196 * @param stringIndex CONSTANT_String_info.string_index item.
197 */
198 public CLConstantStringInfo(int stringIndex) {
199 super.tag = CONSTANT_String;
200 this.stringIndex = stringIndex;
201 }
202
203 /**
204 * {@inheritDoc}
205 */
206 public void write(CLOutputStream out) throws IOException {
207 super.write(out);
208 out.writeShort(stringIndex);
209 }
210
211 /**
212 * {@inheritDoc}
213 */
214 public boolean equals(Object other) {
215 if (other instanceof CLConstantStringInfo) {
216 CLConstantStringInfo c = (CLConstantStringInfo) other;
217 if (c.stringIndex == stringIndex) {
218 return true;
219 }
220 }
221 return false;
222 }
223 }
224
225 /**
226 * Representation of CONSTANT_Integer_info structure.
227 */
228 class CLConstantIntegerInfo extends CLCPInfo {
229 /**
230 * The int number.
231 */
232 public int i;
233
234 /**
235 * Constructs a CLConstantIntegerInfo object.
236 *
237 * @param i the int number.
238 */
239 public CLConstantIntegerInfo(int i) {
240 super.tag = CONSTANT_Integer;
241 this.i = i;
242 }
243
244 /**
245 * Returns CONSTANT_Integer_info.bytes item.
246 *
247 * @return CONSTANT_Integer_info.bytes item.
248 */
249 public short[] bytes() {
250 short[] s = new short[4];
251 short mask = 0xFF;
252 int k = i;
253 for (int j = 0; j < 4; j++) {
254 s[3 - j] = (short) (k & mask);
255 k >>>= 8;
256 }
257 return s;
258 }
259
260 /**
261 * {@inheritDoc}
262 */
263 public void write(CLOutputStream out) throws IOException {
264 super.write(out);
265
266 // out is cast to DataOutputStream to resolve the writeInt() ambiguity.
267 ((DataOutputStream) out).writeInt(i);
268 }
269
270 /**
271 * {@inheritDoc}
272 */
273 public boolean equals(Object other) {
274 if (other instanceof CLConstantIntegerInfo) {
275 CLConstantIntegerInfo c = (CLConstantIntegerInfo) other;
276 if (c.i == i) {
277 return true;
278 }
279 }
280 return false;
281 }
282 }
283
284 /**
285 * Representation of CONSTANT_Float_info structure.
286 */
287 class CLConstantFloatInfo extends CLCPInfo {
288 /**
289 * The floating-point number.
290 */
291 public float f;
292
293 /**
294 * Constructs a CLConstantFloatInfo object.
295 *
296 * @param f the floating-point number.
297 */
298 public CLConstantFloatInfo(float f) {
299 super.tag = CONSTANT_Float;
300 this.f = f;
301 }
302
303 /**
304 * Returns CONSTANT_Float_info.bytes item.
305 *
306 * @return CONSTANT_Float_info.bytes item.
307 */
308 public short[] bytes() {
309 short[] s = new short[4];
310 short mask = 0xFF;
311 int i = Float.floatToIntBits(f);
312 for (int j = 0; j < 4; j++) {
313 s[3 - j] = (short) (i & mask);
314 i >>>= 8;
315 }
316 return s;
317 }
318
319 /**
320 * {@inheritDoc}
321 */
322 public void write(CLOutputStream out) throws IOException {
323 super.write(out);
324 out.writeFloat(f);
325 }
326
327 /**
328 * {@inheritDoc}
329 */
330 public boolean equals(Object other) {
331 if (other instanceof CLConstantFloatInfo) {
332 CLConstantFloatInfo c = (CLConstantFloatInfo) other;
333 if (c.f == f) {
334 return true;
335 }
336 }
337 return false;
338 }
339 }
340
341 /**
342 * Representation of CONSTANT_Long_info structure.
343 */
344 class CLConstantLongInfo extends CLCPInfo {
345 /**
346 * The long number.
347 */
348 public long l;
349
350 /**
351 * Returns the 8 bytes of the long value.
352 *
353 * @return the 8 bytes of the long value.
354 */
355 private short[] bytes() {
356 short[] s = new short[8];
357 short mask = 0xFF;
358 long k = l;
359 for (int j = 0; j < 8; j++) {
360 s[7 - j] = (short) (k & mask);
361 k >>>= 8;
362 }
363 return s;
364 }
365
366 /**
367 * Constructs a CLConstantLongInfo object.
368 *
369 * @param l the long number.
370 */
371 public CLConstantLongInfo(long l) {
372 super.tag = CONSTANT_Long;
373 this.l = l;
374 }
375
376 /**
377 * Returns CONSTANT_Long_info.low_bytes item.
378 *
379 * @return CONSTANT_Long_info.low_bytes item.
380 */
381 public short[] lowBytes() {
382 short[] s = bytes();
383 short[] l = new short[4];
384 l[0] = s[4];
385 l[1] = s[5];
386 l[2] = s[6];
387 l[3] = s[7];
388 return l;
389 }
390
391 /**
392 * Returns CONSTANT_Long_info.high_bytes item.
393 *
394 * @return CONSTANT_Long_info.high_bytes item.
395 */
396 public short[] highBytes() {
397 short[] s = bytes();
398 short[] h = new short[4];
399 h[0] = s[0];
400 h[1] = s[1];
401 h[2] = s[2];
402 h[3] = s[3];
403 return h;
404 }
405
406 /**
407 * {@inheritDoc}
408 */
409 public void write(CLOutputStream out) throws IOException {
410 super.write(out);
411 out.writeLong(l);
412 }
413
414 /**
415 * {@inheritDoc}
416 */
417 public boolean equals(Object other) {
418 if (other instanceof CLConstantLongInfo) {
419 CLConstantLongInfo c = (CLConstantLongInfo) other;
420 if (c.l == l) {
421 return true;
422 }
423 }
424 return false;
425 }
426 }
427
428 /**
429 * Representation of CONSTANT_Double_info structure.
430 */
431 class CLConstantDoubleInfo extends CLCPInfo {
432 /**
433 * The double precision floating-point number.
434 */
435 public double d;
436
437 /**
438 * Returns the 8 bytes of the double precision floating-point value.
439 *
440 * @return the 8 bytes of the double precision floating-point value.
441 */
442 private short[] bytes() {
443 short[] s = new short[8];
444 short mask = 0xFF;
445 long l = Double.doubleToLongBits(d);
446 for (int j = 0; j < 8; j++) {
447 s[7 - j] = (short) (l & mask);
448 l >>>= 8;
449 }
450 return s;
451 }
452
453 /**
454 * Constructs a CLConstantDoubleInfo object.
455 *
456 * @param d the double precision floating-point number.
457 */
458 public CLConstantDoubleInfo(double d) {
459 super.tag = CONSTANT_Double;
460 this.d = d;
461 }
462
463 /**
464 * Returns CONSTANT_Double_info.low_bytes item.
465 *
466 * @return CONSTANT_Double_info.low_bytes item.
467 */
468 public short[] lowBytes() {
469 short[] s = bytes();
470 short[] l = new short[4];
471 l[0] = s[4];
472 l[1] = s[5];
473 l[2] = s[6];
474 l[3] = s[7];
475 return l;
476 }
477
478 /**
479 * Returns CONSTANT_Double_info.high_bytes item.
480 *
481 * @return CONSTANT_Double_info.high_bytes item.
482 */
483 public short[] highBytes() {
484 short[] s = bytes();
485 short[] h = new short[4];
486 h[0] = s[0];
487 h[1] = s[1];
488 h[2] = s[2];
489 h[3] = s[3];
490 return h;
491 }
492
493 /**
494 * {@inheritDoc}
495 */
496 public void write(CLOutputStream out) throws IOException {
497 super.write(out);
498 out.writeDouble(d);
499 }
500
501 /**
502 * {@inheritDoc}
503 */
504 public boolean equals(Object other) {
505 if (other instanceof CLConstantDoubleInfo) {
506 CLConstantDoubleInfo c = (CLConstantDoubleInfo) other;
507 if (c.d == d) {
508 return true;
509 }
510 }
511 return false;
512 }
513 }
514
515 /**
516 * Representation of CONSTANT_NameAndType_info structure.
517 */
518 class CLConstantNameAndTypeInfo extends CLCPInfo {
519 /**
520 * CONSTANT_NameAndType_info.name_index item.
521 */
522 public int nameIndex;
523
524 /**
525 * CONSTANT_NameAndType_info.descriptor_index item.
526 */
527 public int descriptorIndex;
528
529 /**
530 * Constructs a CLConstantNameAndTypeInfo object.
531 *
532 * @param nameIndex CONSTANT_NameAndType_info.name_index item.
533 * @param descriptorIndex CONSTANT_NameAndType_info.descriptor_index item.
534 */
535 public CLConstantNameAndTypeInfo(int nameIndex, int descriptorIndex) {
536 super.tag = CONSTANT_NameAndType;
537 this.nameIndex = nameIndex;
538 this.descriptorIndex = descriptorIndex;
539 }
540
541 /**
542 * {@inheritDoc}
543 */
544 public void write(CLOutputStream out) throws IOException {
545 super.write(out);
546 out.writeShort(nameIndex);
547 out.writeShort(descriptorIndex);
548 }
549
550 /**
551 * {@inheritDoc}
552 */
553
554 public boolean equals(Object other) {
555 if (other instanceof CLConstantNameAndTypeInfo) {
556 CLConstantNameAndTypeInfo c = (CLConstantNameAndTypeInfo) other;
557 if ((c.nameIndex == nameIndex) && (c.descriptorIndex == descriptorIndex)) {
558 return true;
559 }
560 }
561 return false;
562 }
563 }
564
565 /**
566 * Representation of CONSTANT_Utf8_info structure.
567 */
568 class CLConstantUtf8Info extends CLCPInfo {
569 /**
570 * CONSTANT_Utf8_info.bytes item.
571 */
572 public byte[] b;
573
574 /**
575 * Constructs a CLConstantUtf8Info object.
576 *
577 * @param b a constant string value.
578 */
579 public CLConstantUtf8Info(byte[] b) {
580 super.tag = CONSTANT_Utf8;
581 this.b = b;
582 }
583
584 /**
585 * Returns CONSTANT_Utf8_info.length item.
586 *
587 * @return CONSTANT_Utf8_info.length item.
588 */
589 public int length() {
590 return b.length;
591 }
592
593 /**
594 * {@inheritDoc}
595 */
596 public void write(CLOutputStream out) throws IOException {
597 super.write(out);
598 out.writeUTF(new String(b));
599 }
600
601 /**
602 * {@inheritDoc}
603 */
604 public boolean equals(Object other) {
605 if (other instanceof CLConstantUtf8Info) {
606 CLConstantUtf8Info c = (CLConstantUtf8Info) other;
607 if ((new String(b)).equals(new String(c.b))) {
608 return true;
609 }
610 }
611 return false;
612 }
613 }
614