My Java Assignment 2
Assignment 2/.DS_Store
__MACOSX/Assignment 2/._.DS_Store
Assignment 2/Assignment 2.iml
Assignment 2/.idea/uiDesigner.xml
Assignment 2/.idea/.gitignore
# Default ignored files /shelf/ /workspace.xml
Assignment 2/.idea/workspace.xml
1592102201333 1592102201333
Assignment 2/.idea/modules.xml
Assignment 2/.idea/misc.xml
Assignment 2/src/.DS_Store
__MACOSX/Assignment 2/src/._.DS_Store
Assignment 2/.idea/codeStyles/codeStyleConfig.xml
Assignment 2/.idea/libraries/org_hamcrest_hamcrest_2_2.xml
Assignment 2/src/main/.DS_Store
__MACOSX/Assignment 2/src/main/._.DS_Store
Assignment 2/src/main/ca/.DS_Store
__MACOSX/Assignment 2/src/main/ca/._.DS_Store
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic1Tests.java
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic1Tests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
ShortMagic1Tests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 4 bytes to be available, have: 1"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/ByteUtils.java
Assignment 2/src/test/ca/bcit/comp2526/ByteUtils.java
package
ca
.
bcit
.
comp2526
;
import
java
.
io
.
ByteArrayOutputStream
;
import
java
.
io
.
DataOutputStream
;
import
java
.
io
.
IOException
;
public
final
class
ByteUtils
{
private
ByteUtils
()
{
throw
new
IllegalStateException
(
"Do not create instances"
);
}
public
static
byte
[]
byteToBytes
(
final
byte
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeByte
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
unsignedByteToBytes
(
final
int
value
)
throws
IOException
{
final
byte
[]
bytes
;
bytes
=
byteToBytes
((
byte
)
value
);
return
bytes
;
}
public
static
byte
[]
shortToBytes
(
final
short
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeShort
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
unsignedShortToBytes
(
final
int
value
)
throws
IOException
{
final
byte
[]
bytes
;
bytes
=
shortToBytes
((
short
)
value
);
return
bytes
;
}
public
static
byte
[]
intToBytes
(
final
int
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeInt
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
unsignedIntToBytes
(
final
long
value
)
throws
IOException
{
final
byte
[]
bytes
;
bytes
=
intToBytes
((
int
)
value
);
return
bytes
;
}
public
static
byte
[]
longToBytes
(
final
long
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeLong
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
floatToBytes
(
final
float
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeFloat
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
doubleToBytes
(
final
double
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeDouble
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
public
static
byte
[]
stringToBytes
(
final
String
value
)
throws
IOException
{
final
ByteArrayOutputStream
byteStream
;
byteStream
=
new
ByteArrayOutputStream
();
try
(
final
var stream
=
new
DataOutputStream
(
byteStream
))
{
final
byte
[]
bytes
;
stream
.
writeBytes
(
value
);
bytes
=
byteStream
.
toByteArray
();
return
bytes
;
}
}
}
Assignment 2/src/test/ca/bcit/comp2526/ShortMinorTests.java
Assignment 2/src/test/ca/bcit/comp2526/ShortMinorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
ShortMinorTests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 2 bytes to be available, have: 1"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/ShortMajorTests.java
Assignment 2/src/test/ca/bcit/comp2526/ShortMajorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
ShortMajorTests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x00
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 2 bytes to be available, have: 1"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/MissingMinorTests.java
Assignment 2/src/test/ca/bcit/comp2526/MissingMinorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
MissingMinorTests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 2 bytes to be available, have: 0"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/MissingMajorTests.java
Assignment 2/src/test/ca/bcit/comp2526/MissingMajorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
MissingMajorTests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 2 bytes to be available, have: 0"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/TooLowMajorTests.java
Assignment 2/src/test/ca/bcit/comp2526/TooLowMajorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
TooLowMajorTests
extends
ClassFileTest
{
@
Test
public
void
majorTooLow1
()
{
final
InvalidMajorVersionException
ex
;
ex
=
assertThrows
(
InvalidMajorVersionException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x2C
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Major number must be between 45 and 55, was: 44"
));
}
@
Test
public
void
majorTooLow2
()
{
final
InvalidMajorVersionException
ex
;
ex
=
assertThrows
(
InvalidMajorVersionException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x2B
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Major number must be between 45 and 55, was: 43"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/ClassFileTest.java
Assignment 2/src/test/ca/bcit/comp2526/ClassFileTest.java
package
ca
.
bcit
.
comp2526
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
abstract
class
ClassFileTest
{
protected
ClassFile
createClassFile
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
try
(
final
DataInputStream
stream
=
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)))
{
final
ClassFile
classFile
;
classFile
=
new
ClassFile
(
stream
);
return
classFile
;
}
}
}
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic3Tests.java
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic3Tests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
ShortMagic3Tests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 4 bytes to be available, have: 3"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/BadMagicTests.java
Assignment 2/src/test/ca/bcit/comp2526/BadMagicTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
BadMagicTests
extends
ClassFileTest
{
@
Test
public
void
badMagicNumber1
()
{
final
InvalidMagicNumberException
ex
;
ex
=
assertThrows
(
InvalidMagicNumberException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBD
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Magic number must be 0xCAFEBABE, was: 0xCAFEBABD"
));
}
@
Test
public
void
badMagicNumber2
()
{
final
InvalidMagicNumberException
ex
;
ex
=
assertThrows
(
InvalidMagicNumberException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBC
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Magic number must be 0xCAFEBABE, was: 0xCAFEBABC"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/MissingMagicTests.java
Assignment 2/src/test/ca/bcit/comp2526/MissingMagicTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
MissingMagicTests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]{}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 4 bytes to be available, have: 0"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/TooHighMajorTests.java
Assignment 2/src/test/ca/bcit/comp2526/TooHighMajorTests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
TooHighMajorTests
extends
ClassFileTest
{
@
Test
public
void
majorTooHigh1
()
{
final
InvalidMajorVersionException
ex
;
ex
=
assertThrows
(
InvalidMajorVersionException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x38
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Major number must be between 45 and 55, was: 56"
));
}
@
Test
public
void
majorTooHigh2
()
{
final
InvalidMajorVersionException
ex
;
ex
=
assertThrows
(
InvalidMajorVersionException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
,
(
byte
)
0xBA
,
(
byte
)
0xBE
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x00
,
(
byte
)
0x39
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Major number must be between 45 and 55, was: 57"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic2Tests.java
Assignment 2/src/test/ca/bcit/comp2526/ShortMagic2Tests.java
package
ca
.
bcit
.
comp2526
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
class
ShortMagic2Tests
extends
ClassFileTest
{
@
Test
public
void
createClassFile
()
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createClassFile
(
new
byte
[]
{
(
byte
)
0xCA
,
(
byte
)
0xFE
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"Require 4 bytes to be available, have: 2"
));
}
}
Assignment 2/src/main/ca/bcit/comp2526/StreamUtils.java
Assignment 2/src/main/ca/bcit/comp2526/StreamUtils.java
package
ca
.
bcit
.
comp2526
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
java
.
io
.
InputStream
;
public
final
class
StreamUtils
{
private
StreamUtils
()
{
throw
new
IllegalStateException
(
"Do not instantiate"
);
}
// this has issues, but will do for now
private
static
void
checkAvailable
(
final
InputStream
stream
,
final
int
required
)
throws
IOException
,
NotEnoughDataException
{
final
int
available
;
available
=
stream
.
available
();
if
(
available
<
required
)
{
throw
new
NotEnoughDataException
(
required
,
available
);
}
}
public
static
void
readBytes
(
final
DataInputStream
stream
,
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
bytes
.
length
);
stream
.
readFully
(
bytes
);
}
public
static
byte
readByte
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
byte
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
1
);
value
=
stream
.
readByte
();
return
value
;
}
public
static
short
readUnsignedByte
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
byte
value
;
final
short
unsigned
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
1
);
value
=
readByte
(
stream
);
// Why isn't there a Byte.toUnsignedShort?!
unsigned
=
(
short
)
Byte
.
toUnsignedInt
(
value
);
return
unsigned
;
}
public
static
short
readShort
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
short
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
2
);
value
=
stream
.
readShort
();
return
value
;
}
public
static
int
readUnsignedShort
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
short
value
;
final
int
unsigned
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
2
);
value
=
readShort
(
stream
);
unsigned
=
Short
.
toUnsignedInt
(
value
);
return
unsigned
;
}
public
static
int
readInt
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
int
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
4
);
value
=
stream
.
readInt
();
return
value
;
}
public
static
long
readUnsignedInt
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
int
value
;
final
long
unsigned
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
4
);
value
=
readInt
(
stream
);
unsigned
=
Integer
.
toUnsignedLong
(
value
);
return
unsigned
;
}
public
static
float
readFloat
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
float
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
4
);
value
=
stream
.
readFloat
();
return
value
;
}
public
static
long
readLong
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
long
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
8
);
value
=
stream
.
readLong
();
return
value
;
}
public
static
double
readDouble
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
final
double
value
;
if
(
stream
==
null
)
{
throw
new
IllegalArgumentException
(
"stream cannot be null"
);
}
checkAvailable
(
stream
,
8
);
value
=
stream
.
readDouble
();
return
value
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/InvalidReferenceKindException.java
Assignment 2/src/main/ca/bcit/comp2526/InvalidReferenceKindException.java
package
ca
.
bcit
.
comp2526
;
public
class
InvalidReferenceKindException
extends
ClassFileException
{
private
final
short
value
;
public
InvalidReferenceKindException
(
final
short
val
)
{
super
(
"referenceKind must be between 1 and 9, was: "
+
val
);
value
=
val
;
}
public
short
getValue
()
{
return
value
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/InvalidMajorVersionException.java
Assignment 2/src/main/ca/bcit/comp2526/InvalidMajorVersionException.java
package
ca
.
bcit
.
comp2526
;
public
class
InvalidMajorVersionException
extends
ClassFileException
{
private
final
int
major
;
public
InvalidMajorVersionException
(
final
int
actual
,
final
int
smallest
,
final
int
largest
)
{
super
(
String
.
format
(
"Major number must be between %d and %d, was: %d"
,
smallest
,
largest
,
actual
));
major
=
actual
;
}
public
int
getMajor
()
{
return
major
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/ClassFile.java
Assignment 2/src/main/ca/bcit/comp2526/ClassFile.java
package
ca
.
bcit
.
comp2526
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ClassFile
{
public
static
final
long
MAGIC_NUMBER
;
public
static
final
int
MIN_MAJOR
;
public
static
final
int
MAX_MAJOR
;
private
final
long
magicNumber
;
private
final
int
minorVersion
;
private
final
int
majorVersion
;
static
{
MAGIC_NUMBER
=
0xCAFEBABEL
;
MIN_MAJOR
=
45
;
MAX_MAJOR
=
55
;
}
public
ClassFile
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidMagicNumberException
,
InvalidMajorVersionException
{
magicNumber
=
StreamUtils
.
readUnsignedInt
(
stream
);
if
(
magicNumber
!=
MAGIC_NUMBER
)
{
throw
new
InvalidMagicNumberException
(
magicNumber
);
}
minorVersion
=
StreamUtils
.
readUnsignedShort
(
stream
);
majorVersion
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
majorVersion
<
MIN_MAJOR
||
majorVersion
>
MAX_MAJOR
)
{
throw
new
InvalidMajorVersionException
(
majorVersion
,
MIN_MAJOR
,
MAX_MAJOR
);
}
}
public
long
getMagicNumber
()
{
return
magicNumber
;
}
public
int
getMinorVersion
()
{
return
minorVersion
;
}
public
int
getMajorVersion
()
{
return
majorVersion
;
}
}
__MACOSX/Assignment 2/src/main/ca/bcit/comp2526/._ClassFile.java
Assignment 2/src/main/ca/bcit/comp2526/NotEnoughDataException.java
Assignment 2/src/main/ca/bcit/comp2526/NotEnoughDataException.java
package
ca
.
bcit
.
comp2526
;
public
class
NotEnoughDataException
extends
Exception
{
private
final
int
expected
;
private
final
int
actual
;
public
NotEnoughDataException
(
final
int
expected
,
final
int
actual
)
{
super
(
String
.
format
(
"Require %d bytes to be available, have: %d"
,
expected
,
actual
));
this
.
expected
=
expected
;
this
.
actual
=
actual
;
}
public
int
getExpected
()
{
return
expected
;
}
public
int
getActual
()
{
return
actual
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/InvalidConstantPoolTagException.java
Assignment 2/src/main/ca/bcit/comp2526/InvalidConstantPoolTagException.java
package
ca
.
bcit
.
comp2526
;
public
class
InvalidConstantPoolTagException
extends
ClassFileException
{
private
short
tag
;
public
InvalidConstantPoolTagException
(
final
short
t
)
{
super
(
"tag must be one of 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20, was: "
+
t
);
tag
=
t
;
}
public
short
getTag
()
{
return
tag
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/InvalidMagicNumberException.java
Assignment 2/src/main/ca/bcit/comp2526/InvalidMagicNumberException.java
package
ca
.
bcit
.
comp2526
;
public
class
InvalidMagicNumberException
extends
ClassFileException
{
private
final
long
magicNumber
;
public
InvalidMagicNumberException
(
final
long
actual
)
{
super
(
String
.
format
(
"Magic number must be 0x%08X, was: 0x%08X"
,
ClassFile
.
MAGIC_NUMBER
,
actual
));
magicNumber
=
actual
;
}
public
long
getMagicNumber
()
{
return
magicNumber
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/InvalidConstantPoolIndexException.java
Assignment 2/src/main/ca/bcit/comp2526/InvalidConstantPoolIndexException.java
package
ca
.
bcit
.
comp2526
;
public
class
InvalidConstantPoolIndexException
extends
ClassFileException
{
private
final
int
index
;
public
InvalidConstantPoolIndexException
(
final
String
name
,
final
int
idx
)
{
super
(
String
.
format
(
"%s must be > 0, was: %d"
,
name
,
idx
));
index
=
idx
;
}
public
int
getIndex
()
{
return
index
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/ClassFileException.java
Assignment 2/src/main/ca/bcit/comp2526/ClassFileException.java
package
ca
.
bcit
.
comp2526
;
public
class
ClassFileException
extends
Exception
{
public
ClassFileException
(
final
String
msg
)
{
super
(
msg
);
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryInvokeDynamicTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryInvokeDynamicTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryInvokeDynamicTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryInvokeDynamic
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryInvokeDynamic
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryInvokeDynamic
entry
;
entry
=
new
ConstantPoolEntryInvokeDynamic
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadBootstrapMethodAttrIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"bootstrapMethodAttrIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameAndTypeIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
INVOKE_DYNAMIC
);
testGetType
(
entryB
,
ConstantPoolType
.
INVOKE_DYNAMIC
);
}
@
Test
public
void
testGetBootstrapMethodAttrIndex
()
{
assertThat
(
entryA
.
getBootstrapMethodAttrIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getBootstrapMethodAttrIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetNameAndTypeIndex
()
{
assertThat
(
entryA
.
getNameAndTypeIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getNameAndTypeIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryPackageTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryPackageTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryPackageTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryPackage
>
{
public
ConstantPoolEntryPackageTest
()
{
super
(
Short
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
));
}
@
Override
protected
ConstantPoolEntryPackage
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryPackage
entry
;
entry
=
new
ConstantPoolEntryPackage
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
}
@
Test
public
void
testBadNameIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
PACKAGE
);
testGetType
(
entryB
,
ConstantPoolType
.
PACKAGE
);
}
@
Test
public
void
testGetNameIndex
()
{
assertThat
(
entryA
.
getNameIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getNameIndex
(),
equalTo
(
2
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryUTF8Test.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryUTF8Test.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryUTF8Test
extends
ConstantPoolEntryTest
<
ConstantPoolEntryUTF8
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
"Hello"
);
entryB
=
createInstance
(
"Hello, World!"
);
}
private
ConstantPoolEntryUTF8
createInstance
(
final
String
value
)
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
final
byte
[]
bytes
;
final
ConstantPoolEntryUTF8
entry
;
bytes
=
ByteUtils
.
stringToBytes
(
value
);
entry
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
bytes
.
length
),
bytes
);
return
entry
;
}
@
Override
protected
ConstantPoolEntryUTF8
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
final
ConstantPoolEntryUTF8
entry
;
entry
=
new
ConstantPoolEntryUTF8
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
1
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x02
,
0x02
});
testNotEnoughData
(
3
,
2
,
new
byte
[]
{
0x00
,
0x03
,
0x02
,
0x01
});
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
UTF8
);
testGetType
(
entryB
,
ConstantPoolType
.
UTF8
);
}
@
Test
public
void
getGetBytes
()
{
assertThat
(
entryA
.
getBytes
(),
equalTo
(
"Hello"
.
getBytes
()));
assertThat
(
entryB
.
getBytes
(),
equalTo
(
"Hello, World!"
.
getBytes
()));
}
@
Test
public
void
testGetString
()
{
assertThat
(
entryA
.
getString
(),
equalTo
(
"Hello"
));
assertThat
(
entryB
.
getString
(),
equalTo
(
"Hello, World!"
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/MethodHandleKindTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/MethodHandleKindTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidReferenceKindException
;
import
org
.
hamcrest
.
CoreMatchers
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
class
MethodHandleKindTest
{
@
Test
void
testGetType
()
{
assertThat
(
MethodHandleKind
.
GET_FIELD
.
getType
(),
equalTo
((
short
)
1
));
assertThat
(
MethodHandleKind
.
GET_STATIC
.
getType
(),
equalTo
((
short
)
2
));
assertThat
(
MethodHandleKind
.
PUT_FIELD
.
getType
(),
equalTo
((
short
)
3
));
assertThat
(
MethodHandleKind
.
PUT_STATIC
.
getType
(),
equalTo
((
short
)
4
));
assertThat
(
MethodHandleKind
.
INVOKE_VIRTUAL
.
getType
(),
equalTo
((
short
)
5
));
assertThat
(
MethodHandleKind
.
INVOKE_STATIC
.
getType
(),
equalTo
((
short
)
6
));
assertThat
(
MethodHandleKind
.
INVOKE_SPECIAL
.
getType
(),
equalTo
((
short
)
7
));
assertThat
(
MethodHandleKind
.
NEW_INVOKE_SPECIAL
.
getType
(),
equalTo
((
short
)
8
));
assertThat
(
MethodHandleKind
.
INVOKE_INTERFACE
.
getType
(),
equalTo
((
short
)
9
));
}
@
Test
void
fromType
()
throws
InvalidReferenceKindException
{
assertThat
(
MethodHandleKind
.
fromType
((
short
)
1
),
equalTo
(
MethodHandleKind
.
GET_FIELD
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
2
),
equalTo
(
MethodHandleKind
.
GET_STATIC
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
3
),
equalTo
(
MethodHandleKind
.
PUT_FIELD
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
4
),
equalTo
(
MethodHandleKind
.
PUT_STATIC
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
5
),
equalTo
(
MethodHandleKind
.
INVOKE_VIRTUAL
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
6
),
equalTo
(
MethodHandleKind
.
INVOKE_STATIC
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
7
),
equalTo
(
MethodHandleKind
.
INVOKE_SPECIAL
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
8
),
equalTo
(
MethodHandleKind
.
NEW_INVOKE_SPECIAL
));
assertThat
(
MethodHandleKind
.
fromType
((
short
)
9
),
equalTo
(
MethodHandleKind
.
INVOKE_INTERFACE
));
}
@
Test
void
fromBadType
()
{
fromBadType
((
short
)
0
);
fromBadType
((
short
)
10
);
fromBadType
((
short
)
1223
);
}
void
fromBadType
(
final
short
type
)
{
final
InvalidReferenceKindException
ex
;
ex
=
assertThrows
(
InvalidReferenceKindException
.
class
,
()
->
MethodHandleKind
.
fromType
(
type
));
assertThat
(
ex
.
getMessage
(),
CoreMatchers
.
equalTo
(
String
.
format
(
"referenceKind must be between 1 and 9, was: %d"
,
type
)));
}
@
Test
void
values
()
{
// NOTE that .values() is a method that is provided by the compiler.
// DO NOT CREATE A "values" METHOD!
assertThat
(
MethodHandleKind
.
values
(),
equalTo
(
new
MethodHandleKind
[]
{
MethodHandleKind
.
GET_FIELD
,
MethodHandleKind
.
GET_STATIC
,
MethodHandleKind
.
PUT_FIELD
,
MethodHandleKind
.
PUT_STATIC
,
MethodHandleKind
.
INVOKE_VIRTUAL
,
MethodHandleKind
.
INVOKE_STATIC
,
MethodHandleKind
.
INVOKE_SPECIAL
,
MethodHandleKind
.
NEW_INVOKE_SPECIAL
,
MethodHandleKind
.
INVOKE_INTERFACE
,
}));
}
@
Test
void
valueOf
()
{
// NOTE that .valueOf() is a method that is provided by the compiler.
// DO NOT CREATE A "valueOf" METHOD!
assertThat
(
MethodHandleKind
.
valueOf
(
"GET_FIELD"
),
equalTo
(
MethodHandleKind
.
GET_FIELD
));
assertThat
(
MethodHandleKind
.
valueOf
(
"GET_STATIC"
),
equalTo
(
MethodHandleKind
.
GET_STATIC
));
assertThat
(
MethodHandleKind
.
valueOf
(
"PUT_FIELD"
),
equalTo
(
MethodHandleKind
.
PUT_FIELD
));
assertThat
(
MethodHandleKind
.
valueOf
(
"PUT_STATIC"
),
equalTo
(
MethodHandleKind
.
PUT_STATIC
));
assertThat
(
MethodHandleKind
.
valueOf
(
"INVOKE_VIRTUAL"
),
equalTo
(
MethodHandleKind
.
INVOKE_VIRTUAL
));
assertThat
(
MethodHandleKind
.
valueOf
(
"INVOKE_STATIC"
),
equalTo
(
MethodHandleKind
.
INVOKE_STATIC
));
assertThat
(
MethodHandleKind
.
valueOf
(
"INVOKE_SPECIAL"
),
equalTo
(
MethodHandleKind
.
INVOKE_SPECIAL
));
assertThat
(
MethodHandleKind
.
valueOf
(
"NEW_INVOKE_SPECIAL"
),
equalTo
(
MethodHandleKind
.
NEW_INVOKE_SPECIAL
));
assertThat
(
MethodHandleKind
.
valueOf
(
"INVOKE_INTERFACE"
),
equalTo
(
MethodHandleKind
.
INVOKE_INTERFACE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryFieldTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryFieldTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryFieldTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryField
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryField
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryField
entry
;
entry
=
new
ConstantPoolEntryField
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadClassIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"classIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameAndTypeIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
FIELD
);
testGetType
(
entryB
,
ConstantPoolType
.
FIELD
);
}
@
Test
public
void
testGetClassIndex
()
{
assertThat
(
entryA
.
getClassIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getClassIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetNameAndTypeIndex
()
{
assertThat
(
entryA
.
getNameAndTypeIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getNameAndTypeIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryDynamicTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryDynamicTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryDynamicTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryDynamic
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryDynamic
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryDynamic
entry
;
entry
=
new
ConstantPoolEntryDynamic
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadBootstrapMethodAttrIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"bootstrapMethodAttrIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameAndTypeIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
DYNAMIC
);
testGetType
(
entryB
,
ConstantPoolType
.
DYNAMIC
);
}
@
Test
public
void
testGetBootstrapMethodAttrIndex
()
{
assertThat
(
entryA
.
getBootstrapMethodAttrIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getBootstrapMethodAttrIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetNameAndTypeIndex
()
{
assertThat
(
entryA
.
getNameAndTypeIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getNameAndTypeIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryStringTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryStringTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryStringTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryString
>
{
public
ConstantPoolEntryStringTest
()
{
super
(
Short
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
));
}
@
Override
protected
ConstantPoolEntryString
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryString
entry
;
entry
=
new
ConstantPoolEntryString
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
}
@
Test
public
void
testBadStringIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"stringIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
STRING
);
testGetType
(
entryB
,
ConstantPoolType
.
STRING
);
}
@
Test
public
void
testGetStringIndex
()
{
assertThat
(
entryA
.
getStringIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getStringIndex
(),
equalTo
(
2
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryDoubleTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryDoubleTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryDoubleTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryDouble
>
{
public
ConstantPoolEntryDoubleTest
()
{
super
(
Double
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
{
entryA
=
createInstance
(
ByteUtils
.
doubleToBytes
(
Double
.
MAX_VALUE
));
entryB
=
createInstance
(
ByteUtils
.
doubleToBytes
(
Double
.
MIN_VALUE
));
}
@
Override
protected
ConstantPoolEntryDouble
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
final
ConstantPoolEntryDouble
entry
;
entry
=
new
ConstantPoolEntryDouble
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
2
);
testGetNumberOfSlots
(
entryB
,
2
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
DOUBLE
);
testGetType
(
entryB
,
ConstantPoolType
.
DOUBLE
);
}
@
Test
public
void
testGetValue
()
{
assertThat
(
entryA
.
getValue
(),
equalTo
(
Double
.
MAX_VALUE
));
assertThat
(
entryB
.
getValue
(),
equalTo
(
Double
.
MIN_VALUE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryIntegerTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryIntegerTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryIntegerTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryInteger
>
{
public
ConstantPoolEntryIntegerTest
()
{
super
(
Integer
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
{
entryA
=
createInstance
(
ByteUtils
.
intToBytes
(
Integer
.
MAX_VALUE
));
entryB
=
createInstance
(
ByteUtils
.
intToBytes
(
Integer
.
MIN_VALUE
));
}
@
Override
protected
ConstantPoolEntryInteger
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
final
ConstantPoolEntryInteger
entry
;
entry
=
new
ConstantPoolEntryInteger
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
});
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
INTEGER
);
testGetType
(
entryB
,
ConstantPoolType
.
INTEGER
);
}
@
Test
public
void
testGetValue
()
{
assertThat
(
entryA
.
getValue
(),
equalTo
(
Integer
.
MAX_VALUE
));
assertThat
(
entryB
.
getValue
(),
equalTo
(
Integer
.
MIN_VALUE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryMethodTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryMethod
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryMethod
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryMethod
entry
;
entry
=
new
ConstantPoolEntryMethod
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadClassIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"classIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameAndTypeIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
METHOD
);
testGetType
(
entryB
,
ConstantPoolType
.
METHOD
);
}
@
Test
public
void
testGetClassIndex
()
{
assertThat
(
entryA
.
getClassIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getClassIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetNameAndTypeIndex
()
{
assertThat
(
entryA
.
getNameAndTypeIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getNameAndTypeIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryNameAndTypeTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryNameAndTypeTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryNameAndTypeTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryNameAndType
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryNameAndType
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryNameAndType
entry
;
entry
=
new
ConstantPoolEntryNameAndType
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadClassIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadDescriptorIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"descriptorIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
NAME_AND_TYPE
);
testGetType
(
entryB
,
ConstantPoolType
.
NAME_AND_TYPE
);
}
@
Test
public
void
testGetNameIndex
()
{
assertThat
(
entryA
.
getNameIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getNameIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetDescriptorIndex
()
{
assertThat
(
entryA
.
getDescriptorIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getDescriptorIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryInterfaceMethodTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryInterfaceMethodTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryInterfaceMethodTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryInterfaceMethod
>
{
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
),
ByteUtils
.
unsignedShortToBytes
(
1
));
}
@
Override
protected
ConstantPoolEntryInterfaceMethod
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryInterfaceMethod
entry
;
entry
=
new
ConstantPoolEntryInterfaceMethod
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
2
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x00
,
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x00
,
0x01
,
0x02
});
}
@
Test
public
void
testBadClassIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
),
ByteUtils
.
unsignedShortToBytes
(
1
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"classIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameAndTypeIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
INTERFACE_METHOD
);
testGetType
(
entryB
,
ConstantPoolType
.
INTERFACE_METHOD
);
}
@
Test
public
void
testGetClassIndex
()
{
assertThat
(
entryA
.
getClassIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getClassIndex
(),
equalTo
(
2
));
}
@
Test
public
void
testGetNameAndTypeIndex
()
{
assertThat
(
entryA
.
getNameAndTypeIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getNameAndTypeIndex
(),
equalTo
(
1
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodHandleTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodHandleTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
*
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryMethodHandleTest
extends
ConstantPoolEntryTest
<
ConstantPoolEntryMethodHandle
>
{
private
ConstantPoolEntryMethodHandle
entryC
;
private
ConstantPoolEntryMethodHandle
entryD
;
private
ConstantPoolEntryMethodHandle
entryE
;
private
ConstantPoolEntryMethodHandle
entryF
;
private
ConstantPoolEntryMethodHandle
entryG
;
private
ConstantPoolEntryMethodHandle
entryH
;
private
ConstantPoolEntryMethodHandle
entryI
;
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
GET_FIELD
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryB
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
GET_STATIC
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
3
));
entryC
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
PUT_FIELD
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
3
));
entryD
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
PUT_STATIC
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryE
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
INVOKE_VIRTUAL
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryF
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
INVOKE_STATIC
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
3
));
entryG
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
INVOKE_SPECIAL
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
2
));
entryH
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
NEW_INVOKE_SPECIAL
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
3
));
entryI
=
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
MethodHandleKind
.
INVOKE_INTERFACE
.
getType
()),
ByteUtils
.
unsignedShortToBytes
(
3
));
}
@
Override
protected
ConstantPoolEntryMethodHandle
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidReferenceKindException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryMethodHandle
entry
;
entry
=
new
ConstantPoolEntryMethodHandle
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
1
,
0
,
new
byte
[]
{});
testNotEnoughData
(
2
,
0
,
new
byte
[]
{
0x01
});
testNotEnoughData
(
2
,
1
,
new
byte
[]
{
0x01
,
0x01
});
}
@
Test
public
void
testBadReferenceKind
()
{
final
InvalidReferenceKindException
ex
;
ex
=
assertThrows
(
InvalidReferenceKindException
.
class
,
()
->
createInstance
(
new
byte
[]
{
0x00
}));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"referenceKind must be between 1 and 9, was: 0"
));
assertThat
(
ex
.
getValue
(),
equalTo
((
short
)
0
));
}
@
Test
public
void
testBadNameAndTypeIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedByteToBytes
(
1
),
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"referenceIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
testGetNumberOfSlots
(
entryC
,
1
);
testGetNumberOfSlots
(
entryD
,
1
);
testGetNumberOfSlots
(
entryE
,
1
);
testGetNumberOfSlots
(
entryF
,
1
);
testGetNumberOfSlots
(
entryG
,
1
);
testGetNumberOfSlots
(
entryH
,
1
);
testGetNumberOfSlots
(
entryI
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryB
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryC
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryD
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryE
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryF
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryG
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryH
,
ConstantPoolType
.
METHOD_HANDLE
);
testGetType
(
entryI
,
ConstantPoolType
.
METHOD_HANDLE
);
}
@
Test
public
void
testGetReferenceKind
()
{
assertThat
(
entryA
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
GET_FIELD
));
assertThat
(
entryB
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
GET_STATIC
));
assertThat
(
entryC
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
PUT_FIELD
));
assertThat
(
entryD
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
PUT_STATIC
));
assertThat
(
entryE
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
INVOKE_VIRTUAL
));
assertThat
(
entryF
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
INVOKE_STATIC
));
assertThat
(
entryG
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
INVOKE_SPECIAL
));
assertThat
(
entryH
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
NEW_INVOKE_SPECIAL
));
assertThat
(
entryI
.
getReferenceKind
(),
equalTo
(
MethodHandleKind
.
INVOKE_INTERFACE
));
}
@
Test
public
void
testGetReferenceIndex
()
{
assertThat
(
entryA
.
getReferenceIndex
(),
equalTo
(
2
));
assertThat
(
entryB
.
getReferenceIndex
(),
equalTo
(
3
));
assertThat
(
entryC
.
getReferenceIndex
(),
equalTo
(
3
));
assertThat
(
entryD
.
getReferenceIndex
(),
equalTo
(
2
));
assertThat
(
entryE
.
getReferenceIndex
(),
equalTo
(
2
));
assertThat
(
entryF
.
getReferenceIndex
(),
equalTo
(
3
));
assertThat
(
entryG
.
getReferenceIndex
(),
equalTo
(
2
));
assertThat
(
entryH
.
getReferenceIndex
(),
equalTo
(
3
));
assertThat
(
entryI
.
getReferenceIndex
(),
equalTo
(
3
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolTypeTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolTypeTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolTagException
;
import
org
.
hamcrest
.
CoreMatchers
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
*
;
class
ConstantPoolTypeTest
{
@
Test
void
getTag
()
{
assertThat
(
ConstantPoolType
.
UTF8
.
getTag
(),
equalTo
((
short
)
1
));
assertThat
(
ConstantPoolType
.
INTEGER
.
getTag
(),
equalTo
((
short
)
3
));
assertThat
(
ConstantPoolType
.
FLOAT
.
getTag
(),
equalTo
((
short
)
4
));
assertThat
(
ConstantPoolType
.
LONG
.
getTag
(),
equalTo
((
short
)
5
));
assertThat
(
ConstantPoolType
.
DOUBLE
.
getTag
(),
equalTo
((
short
)
6
));
assertThat
(
ConstantPoolType
.
CLASS
.
getTag
(),
equalTo
((
short
)
7
));
assertThat
(
ConstantPoolType
.
STRING
.
getTag
(),
equalTo
((
short
)
8
));
assertThat
(
ConstantPoolType
.
FIELD
.
getTag
(),
equalTo
((
short
)
9
));
assertThat
(
ConstantPoolType
.
METHOD
.
getTag
(),
equalTo
((
short
)
10
));
assertThat
(
ConstantPoolType
.
INTERFACE_METHOD
.
getTag
(),
equalTo
((
short
)
11
));
assertThat
(
ConstantPoolType
.
NAME_AND_TYPE
.
getTag
(),
equalTo
((
short
)
12
));
assertThat
(
ConstantPoolType
.
METHOD_HANDLE
.
getTag
(),
equalTo
((
short
)
15
));
assertThat
(
ConstantPoolType
.
METHOD_TYPE
.
getTag
(),
equalTo
((
short
)
16
));
assertThat
(
ConstantPoolType
.
DYNAMIC
.
getTag
(),
equalTo
((
short
)
17
));
assertThat
(
ConstantPoolType
.
INVOKE_DYNAMIC
.
getTag
(),
equalTo
((
short
)
18
));
assertThat
(
ConstantPoolType
.
MODULE
.
getTag
(),
equalTo
((
short
)
19
));
assertThat
(
ConstantPoolType
.
PACKAGE
.
getTag
(),
equalTo
((
short
)
20
));
}
@
Test
void
fromTag
()
throws
InvalidConstantPoolTagException
{
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
1
),
equalTo
(
ConstantPoolType
.
UTF8
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
3
),
equalTo
(
ConstantPoolType
.
INTEGER
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
4
),
equalTo
(
ConstantPoolType
.
FLOAT
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
5
),
equalTo
(
ConstantPoolType
.
LONG
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
6
),
equalTo
(
ConstantPoolType
.
DOUBLE
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
7
),
equalTo
(
ConstantPoolType
.
CLASS
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
8
),
equalTo
(
ConstantPoolType
.
STRING
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
9
),
equalTo
(
ConstantPoolType
.
FIELD
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
10
),
equalTo
(
ConstantPoolType
.
METHOD
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
11
),
equalTo
(
ConstantPoolType
.
INTERFACE_METHOD
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
12
),
equalTo
(
ConstantPoolType
.
NAME_AND_TYPE
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
15
),
equalTo
(
ConstantPoolType
.
METHOD_HANDLE
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
16
),
equalTo
(
ConstantPoolType
.
METHOD_TYPE
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
17
),
equalTo
(
ConstantPoolType
.
DYNAMIC
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
18
),
equalTo
(
ConstantPoolType
.
INVOKE_DYNAMIC
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
19
),
equalTo
(
ConstantPoolType
.
MODULE
));
assertThat
(
ConstantPoolType
.
fromTag
((
short
)
20
),
equalTo
(
ConstantPoolType
.
PACKAGE
));
}
@
Test
void
fromBadTag
()
{
fromBadTag
((
short
)
0
);
fromBadTag
((
short
)
2
);
fromBadTag
((
short
)
21
);
fromBadTag
((
short
)
23
);
fromBadTag
((
short
)
742
);
}
void
fromBadTag
(
final
short
tag
)
{
final
InvalidConstantPoolTagException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolTagException
.
class
,
()
->
ConstantPoolType
.
fromTag
(
tag
));
assertThat
(
ex
.
getMessage
(),
CoreMatchers
.
equalTo
(
String
.
format
(
"tag must be one of 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20, was: %d"
,
tag
)));
}
@
Test
void
values
()
{
// NOTE that .values() is a method that is provided by the compiler.
// DO NOT CREATE A "values" METHOD!
assertThat
(
ConstantPoolType
.
values
(),
equalTo
(
new
ConstantPoolType
[]
{
ConstantPoolType
.
UTF8
,
ConstantPoolType
.
INTEGER
,
ConstantPoolType
.
FLOAT
,
ConstantPoolType
.
LONG
,
ConstantPoolType
.
DOUBLE
,
ConstantPoolType
.
CLASS
,
ConstantPoolType
.
STRING
,
ConstantPoolType
.
FIELD
,
ConstantPoolType
.
METHOD
,
ConstantPoolType
.
INTERFACE_METHOD
,
ConstantPoolType
.
NAME_AND_TYPE
,
ConstantPoolType
.
METHOD_HANDLE
,
ConstantPoolType
.
METHOD_TYPE
,
ConstantPoolType
.
DYNAMIC
,
ConstantPoolType
.
INVOKE_DYNAMIC
,
ConstantPoolType
.
MODULE
,
ConstantPoolType
.
PACKAGE
,
}));
}
@
Test
void
valueOf
()
{
// NOTE that .valueOf() is a method that is provided by the compiler.
// DO NOT CREATE A "valueOf" METHOD!
assertThat
(
ConstantPoolType
.
valueOf
(
"UTF8"
),
equalTo
(
ConstantPoolType
.
UTF8
));
assertThat
(
ConstantPoolType
.
valueOf
(
"INTEGER"
),
equalTo
(
ConstantPoolType
.
INTEGER
));
assertThat
(
ConstantPoolType
.
valueOf
(
"FLOAT"
),
equalTo
(
ConstantPoolType
.
FLOAT
));
assertThat
(
ConstantPoolType
.
valueOf
(
"LONG"
),
equalTo
(
ConstantPoolType
.
LONG
));
assertThat
(
ConstantPoolType
.
valueOf
(
"DOUBLE"
),
equalTo
(
ConstantPoolType
.
DOUBLE
));
assertThat
(
ConstantPoolType
.
valueOf
(
"CLASS"
),
equalTo
(
ConstantPoolType
.
CLASS
));
assertThat
(
ConstantPoolType
.
valueOf
(
"STRING"
),
equalTo
(
ConstantPoolType
.
STRING
));
assertThat
(
ConstantPoolType
.
valueOf
(
"FIELD"
),
equalTo
(
ConstantPoolType
.
FIELD
));
assertThat
(
ConstantPoolType
.
valueOf
(
"METHOD"
),
equalTo
(
ConstantPoolType
.
METHOD
));
assertThat
(
ConstantPoolType
.
valueOf
(
"INTERFACE_METHOD"
),
equalTo
(
ConstantPoolType
.
INTERFACE_METHOD
));
assertThat
(
ConstantPoolType
.
valueOf
(
"NAME_AND_TYPE"
),
equalTo
(
ConstantPoolType
.
NAME_AND_TYPE
));
assertThat
(
ConstantPoolType
.
valueOf
(
"METHOD_HANDLE"
),
equalTo
(
ConstantPoolType
.
METHOD_HANDLE
));
assertThat
(
ConstantPoolType
.
valueOf
(
"METHOD_TYPE"
),
equalTo
(
ConstantPoolType
.
METHOD_TYPE
));
assertThat
(
ConstantPoolType
.
valueOf
(
"DYNAMIC"
),
equalTo
(
ConstantPoolType
.
DYNAMIC
));
assertThat
(
ConstantPoolType
.
valueOf
(
"INVOKE_DYNAMIC"
),
equalTo
(
ConstantPoolType
.
INVOKE_DYNAMIC
));
assertThat
(
ConstantPoolType
.
valueOf
(
"MODULE"
),
equalTo
(
ConstantPoolType
.
MODULE
));
assertThat
(
ConstantPoolType
.
valueOf
(
"PACKAGE"
),
equalTo
(
ConstantPoolType
.
PACKAGE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryFloatTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryFloatTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryFloatTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryFloat
>
{
public
ConstantPoolEntryFloatTest
()
{
super
(
Float
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
{
entryA
=
createInstance
(
ByteUtils
.
floatToBytes
(
Float
.
MAX_VALUE
));
entryB
=
createInstance
(
ByteUtils
.
floatToBytes
(
Float
.
MIN_VALUE
));
}
@
Override
protected
ConstantPoolEntryFloat
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
final
ConstantPoolEntryFloat
entry
;
entry
=
new
ConstantPoolEntryFloat
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
});
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
FLOAT
);
testGetType
(
entryB
,
ConstantPoolType
.
FLOAT
);
}
@
Test
public
void
testGetValue
()
{
assertThat
(
entryA
.
getValue
(),
equalTo
(
Float
.
MAX_VALUE
));
assertThat
(
entryB
.
getValue
(),
equalTo
(
Float
.
MIN_VALUE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
ByteArrayOutputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
public
abstract
class
ConstantPoolEntryTest
<
T
extends
ConstantPoolEntry
>
{
protected
T entryA
;
protected
T entryB
;
protected
abstract
T createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
ClassFileException
;
protected
final
T createInstance
(
final
byte
[]
...
byteCollection
)
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
try
(
final
ByteArrayOutputStream
stream
=
new
ByteArrayOutputStream
())
{
final
byte
[]
bytes
;
final
T entry
;
for
(
final
byte
[]
array
:
byteCollection
)
{
stream
.
writeBytes
(
array
);
}
bytes
=
stream
.
toByteArray
();
entry
=
createInstance
(
bytes
);
return
entry
;
}
}
protected
final
void
testGetNumberOfSlots
(
final
ConstantPoolEntry
entry
,
final
int
expected
)
{
assertThat
(
entry
.
getNumberOfSlots
(),
equalTo
(
expected
));
}
protected
final
void
testGetType
(
final
ConstantPoolEntry
entry
,
final
ConstantPoolType
expected
)
{
assertThat
(
entry
.
getType
(),
equalTo
(
expected
));
}
protected
final
void
testNotEnoughData
(
final
int
expectedSize
,
final
int
actualSize
,
final
byte
[]
bytes
)
{
final
NotEnoughDataException
ex
;
ex
=
assertThrows
(
NotEnoughDataException
.
class
,
()
->
createInstance
(
bytes
));
assertThat
(
ex
.
getMessage
(),
equalTo
(
String
.
format
(
"Require %d bytes to be available, have: %d"
,
expectedSize
,
actualSize
)));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryClassTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryClassTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryClassTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryClass
>
{
public
ConstantPoolEntryClassTest
()
{
super
(
Short
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
));
}
@
Override
protected
ConstantPoolEntryClass
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryClass
entry
;
entry
=
new
ConstantPoolEntryClass
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
}
@
Test
public
void
testBadNameIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"nameIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
CLASS
);
testGetType
(
entryB
,
ConstantPoolType
.
CLASS
);
}
@
Test
public
void
testGetNameIndex
()
{
assertThat
(
entryA
.
getNameIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getNameIndex
(),
equalTo
(
2
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryLongTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryLongTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryLongTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryLong
>
{
public
ConstantPoolEntryLongTest
()
{
super
(
Long
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
{
entryA
=
createInstance
(
ByteUtils
.
longToBytes
(
Long
.
MAX_VALUE
));
entryB
=
createInstance
(
ByteUtils
.
longToBytes
(
Long
.
MIN_VALUE
));
}
@
Override
protected
ConstantPoolEntryLong
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
{
final
ConstantPoolEntryLong
entry
;
entry
=
new
ConstantPoolEntryLong
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
testNotEnoughData
(
new
byte
[]
{
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
});
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
2
);
testGetNumberOfSlots
(
entryB
,
2
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
LONG
);
testGetType
(
entryB
,
ConstantPoolType
.
LONG
);
}
@
Test
public
void
testGetValue
()
{
assertThat
(
entryA
.
getValue
(),
equalTo
(
Long
.
MAX_VALUE
));
assertThat
(
entryB
.
getValue
(),
equalTo
(
Long
.
MIN_VALUE
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodTypeTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodTypeTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
ByteUtils
;
import
ca
.
bcit
.
comp2526
.
ClassFileException
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
org
.
junit
.
jupiter
.
api
.
BeforeAll
;
import
org
.
junit
.
jupiter
.
api
.
Test
;
import
org
.
junit
.
jupiter
.
api
.
TestInstance
;
import
java
.
io
.
ByteArrayInputStream
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
import
static
org
.
hamcrest
.
CoreMatchers
.
equalTo
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
junit
.
jupiter
.
api
.
Assertions
.
assertThrows
;
@
TestInstance
(
TestInstance
.
Lifecycle
.
PER_CLASS
)
public
class
ConstantPoolEntryMethodTypeTest
extends
ConstantPoolEntryUnaryTest
<
ConstantPoolEntryMethodType
>
{
public
ConstantPoolEntryMethodTypeTest
()
{
super
(
Short
.
BYTES
);
}
@
BeforeAll
public
void
createInstances
()
throws
IOException
,
NotEnoughDataException
,
ClassFileException
{
entryA
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
1
));
entryB
=
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
2
));
}
@
Override
protected
ConstantPoolEntryMethodType
createInstance
(
final
byte
[]
bytes
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
final
ConstantPoolEntryMethodType
entry
;
entry
=
new
ConstantPoolEntryMethodType
(
new
DataInputStream
(
new
ByteArrayInputStream
(
bytes
)));
return
entry
;
}
@
Test
public
void
testNotEnoughData
()
{
testNotEnoughData
(
new
byte
[]
{});
testNotEnoughData
(
new
byte
[]
{
0x00
});
}
@
Test
public
void
testBadNameIndex
()
{
final
InvalidConstantPoolIndexException
ex
;
ex
=
assertThrows
(
InvalidConstantPoolIndexException
.
class
,
()
->
createInstance
(
ByteUtils
.
unsignedShortToBytes
(
0
)));
assertThat
(
ex
.
getMessage
(),
equalTo
(
"descriptorIndex must be > 0, was: 0"
));
assertThat
(
ex
.
getIndex
(),
equalTo
(
0
));
}
@
Test
public
void
testGetNumberOfSlots
()
{
testGetNumberOfSlots
(
entryA
,
1
);
testGetNumberOfSlots
(
entryB
,
1
);
}
@
Test
public
void
testGetType
()
{
testGetType
(
entryA
,
ConstantPoolType
.
METHOD_TYPE
);
testGetType
(
entryB
,
ConstantPoolType
.
METHOD_TYPE
);
}
@
Test
public
void
testGetDescriptorIndex
()
{
assertThat
(
entryA
.
getDescriptorIndex
(),
equalTo
(
1
));
assertThat
(
entryB
.
getDescriptorIndex
(),
equalTo
(
2
));
}
}
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryUnaryTest.java
Assignment 2/src/test/ca/bcit/comp2526/constantpool/ConstantPoolEntryUnaryTest.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
public
abstract
class
ConstantPoolEntryUnaryTest
<
T
extends
ConstantPoolEntry
>
extends
ConstantPoolEntryTest
<
T
>
{
private
final
int
expectedSize
;
protected
ConstantPoolEntryUnaryTest
(
final
int
expected
)
{
expectedSize
=
expected
;
}
protected
final
void
testNotEnoughData
(
final
byte
[]
bytes
)
{
testNotEnoughData
(
expectedSize
,
bytes
);
}
protected
final
void
testNotEnoughData
(
final
int
expectedSize
,
final
byte
[]
bytes
)
{
testNotEnoughData
(
expectedSize
,
bytes
.
length
,
bytes
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodType.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodType.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryMethodType
extends
ConstantPoolEntry
{
private
final
int
descriptorIndex
;
public
ConstantPoolEntryMethodType
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
METHOD_TYPE
);
descriptorIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
descriptorIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"descriptorIndex"
,
descriptorIndex
);
}
}
public
int
getDescriptorIndex
()
{
return
descriptorIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodHandle.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethodHandle.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
InvalidReferenceKindException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryMethodHandle
extends
ConstantPoolEntry
{
private
final
MethodHandleKind
kind
;
private
final
int
referenceIndex
;
public
ConstantPoolEntryMethodHandle
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidReferenceKindException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
METHOD_HANDLE
);
final
short
type
;
type
=
StreamUtils
.
readUnsignedByte
(
stream
);
kind
=
MethodHandleKind
.
fromType
(
type
);
referenceIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
referenceIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"referenceIndex"
,
referenceIndex
);
}
}
public
MethodHandleKind
getReferenceKind
()
{
return
kind
;
}
public
int
getReferenceIndex
()
{
return
referenceIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryAbstractDynamic.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryAbstractDynamic.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryAbstractDynamic
extends
ConstantPoolEntry
{
private
final
int
bootstrapMethodAttrIndex
;
private
final
int
nameAndTypeIndex
;
public
ConstantPoolEntryAbstractDynamic
(
final
ConstantPoolType
type
,
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
type
);
bootstrapMethodAttrIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
bootstrapMethodAttrIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"bootstrapMethodAttrIndex"
,
bootstrapMethodAttrIndex
);
}
nameAndTypeIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
nameAndTypeIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"nameAndTypeIndex"
,
nameAndTypeIndex
);
}
}
public
int
getBootstrapMethodAttrIndex
()
{
return
bootstrapMethodAttrIndex
;
}
public
int
getNameAndTypeIndex
()
{
return
nameAndTypeIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolType.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolType.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolTagException
;
import
java
.
util
.
HashMap
;
import
java
.
util
.
Map
;
public
enum
ConstantPoolType
{
UTF8
((
short
)
1
),
INTEGER
((
short
)
3
),
FLOAT
((
short
)
4
),
LONG
((
short
)
5
),
DOUBLE
((
short
)
6
),
CLASS
((
short
)
7
),
STRING
((
short
)
8
),
FIELD
((
short
)
9
),
METHOD
((
short
)
10
),
INTERFACE_METHOD
((
short
)
11
),
NAME_AND_TYPE
((
short
)
12
),
METHOD_HANDLE
((
short
)
15
),
METHOD_TYPE
((
short
)
16
),
DYNAMIC
((
short
)
17
),
INVOKE_DYNAMIC
((
short
)
18
),
MODULE
((
short
)
19
),
PACKAGE
((
short
)
20
);
private
final
short
tag
;
ConstantPoolType
(
final
short
t
)
{
tag
=
t
;
}
public
short
getTag
()
{
return
tag
;
}
private
static
final
Map
<
Short
,
ConstantPoolType
>
TYPES
;
static
{
TYPES
=
new
HashMap
<>
();
TYPES
.
put
((
short
)
1
,
UTF8
);
TYPES
.
put
((
short
)
3
,
INTEGER
);
TYPES
.
put
((
short
)
4
,
FLOAT
);
TYPES
.
put
((
short
)
5
,
LONG
);
TYPES
.
put
((
short
)
6
,
DOUBLE
);
TYPES
.
put
((
short
)
7
,
CLASS
);
TYPES
.
put
((
short
)
8
,
STRING
);
TYPES
.
put
((
short
)
9
,
FIELD
);
TYPES
.
put
((
short
)
10
,
METHOD
);
TYPES
.
put
((
short
)
11
,
INTERFACE_METHOD
);
TYPES
.
put
((
short
)
12
,
NAME_AND_TYPE
);
TYPES
.
put
((
short
)
15
,
METHOD_HANDLE
);
TYPES
.
put
((
short
)
16
,
METHOD_TYPE
);
TYPES
.
put
((
short
)
17
,
DYNAMIC
);
TYPES
.
put
((
short
)
18
,
INVOKE_DYNAMIC
);
TYPES
.
put
((
short
)
19
,
MODULE
);
TYPES
.
put
((
short
)
20
,
PACKAGE
);
}
public
static
ConstantPoolType
fromTag
(
final
short
tag
)
throws
InvalidConstantPoolTagException
{
final
ConstantPoolType
type
;
type
=
TYPES
.
get
(
tag
);
if
(
type
==
null
)
{
throw
new
InvalidConstantPoolTagException
(
tag
);
}
return
type
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryPrimitive.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryPrimitive.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
abstract
class
ConstantPoolEntryPrimitive
<
T
extends
Number
>
extends
ConstantPoolEntry
{
interface
Filter
<
T
extends
Number
>
{
T apply
(
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
;
}
private
final
T value
;
public
ConstantPoolEntryPrimitive
(
final
ConstantPoolType
type
,
final
int
slots
,
final
DataInputStream
stream
,
final
Filter
<
T
>
filter
)
throws
IOException
,
NotEnoughDataException
{
super
(
type
,
slots
);
value
=
filter
.
apply
(
stream
);
}
public
final
T getValue
()
{
return
value
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntry.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntry.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
public
abstract
class
ConstantPoolEntry
{
private
final
ConstantPoolType
type
;
private
final
int
numberOfSlots
;
protected
ConstantPoolEntry
(
final
ConstantPoolType
t
)
{
this
(
t
,
1
);
}
protected
ConstantPoolEntry
(
final
ConstantPoolType
t
,
final
int
slots
)
{
if
(
slots
<
1
||
slots
>
2
)
{
throw
new
IllegalArgumentException
(
"slots must be 1 or 2, was: "
+
slots
);
}
type
=
t
;
numberOfSlots
=
slots
;
}
public
final
ConstantPoolType
getType
()
{
return
type
;
}
public
final
int
getNumberOfSlots
()
{
return
numberOfSlots
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryLong.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryLong.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryLong
extends
ConstantPoolEntryPrimitive
<
Long
>
{
public
ConstantPoolEntryLong
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
super
(
ConstantPoolType
.
LONG
,
2
,
stream
,
StreamUtils
::
readLong
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/MethodHandleKind.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/MethodHandleKind.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidReferenceKindException
;
import
java
.
util
.
HashMap
;
import
java
.
util
.
Map
;
public
enum
MethodHandleKind
{
GET_FIELD
((
short
)
1
),
GET_STATIC
((
short
)
2
),
PUT_FIELD
((
short
)
3
),
PUT_STATIC
((
short
)
4
),
INVOKE_VIRTUAL
((
short
)
5
),
INVOKE_STATIC
((
short
)
6
),
INVOKE_SPECIAL
((
short
)
7
),
NEW_INVOKE_SPECIAL
((
short
)
8
),
INVOKE_INTERFACE
((
short
)
9
);
private
final
short
type
;
MethodHandleKind
(
final
short
t
)
{
type
=
t
;
}
public
short
getType
()
{
return
type
;
}
private
static
final
Map
<
Short
,
MethodHandleKind
>
TYPES
;
static
{
TYPES
=
new
HashMap
<>
();
TYPES
.
put
((
short
)
1
,
GET_FIELD
);
TYPES
.
put
((
short
)
2
,
GET_STATIC
);
TYPES
.
put
((
short
)
3
,
PUT_FIELD
);
TYPES
.
put
((
short
)
4
,
PUT_STATIC
);
TYPES
.
put
((
short
)
5
,
INVOKE_VIRTUAL
);
TYPES
.
put
((
short
)
6
,
INVOKE_STATIC
);
TYPES
.
put
((
short
)
7
,
INVOKE_SPECIAL
);
TYPES
.
put
((
short
)
8
,
NEW_INVOKE_SPECIAL
);
TYPES
.
put
((
short
)
9
,
INVOKE_INTERFACE
);
}
public
static
MethodHandleKind
fromType
(
final
short
type
)
throws
InvalidReferenceKindException
{
final
MethodHandleKind
kind
;
kind
=
TYPES
.
get
(
type
);
if
(
kind
==
null
)
{
throw
new
InvalidReferenceKindException
(
type
);
}
return
kind
;
}}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryString.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryString.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryString
extends
ConstantPoolEntry
{
private
final
int
stringIndex
;
public
ConstantPoolEntryString
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
STRING
);
stringIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
stringIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"stringIndex"
,
stringIndex
);
}
}
public
int
getStringIndex
()
{
return
stringIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryUTF8.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryUTF8.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryUTF8
extends
ConstantPoolEntry
{
private
final
byte
[]
bytes
;
private
final
String
string
;
public
ConstantPoolEntryUTF8
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
super
(
ConstantPoolType
.
UTF8
);
final
int
length
;
length
=
StreamUtils
.
readUnsignedShort
(
stream
);
bytes
=
new
byte
[
length
];
StreamUtils
.
readBytes
(
stream
,
bytes
);
string
=
new
String
(
bytes
);
}
public
byte
[]
getBytes
()
{
return
bytes
.
clone
();
}
public
String
getString
()
{
return
string
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryField.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryField.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryField
extends
ConstantPoolEntryMember
{
public
ConstantPoolEntryField
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
FIELD
,
stream
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryDynamic.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryDynamic.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryDynamic
extends
ConstantPoolEntryAbstractDynamic
{
public
ConstantPoolEntryDynamic
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
DYNAMIC
,
stream
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethod.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMethod.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryMethod
extends
ConstantPoolEntryMember
{
public
ConstantPoolEntryMethod
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
METHOD
,
stream
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInvokeDynamic.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInvokeDynamic.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryInvokeDynamic
extends
ConstantPoolEntryAbstractDynamic
{
public
ConstantPoolEntryInvokeDynamic
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
INVOKE_DYNAMIC
,
stream
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryPackage.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryPackage.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryPackage
extends
ConstantPoolEntry
{
private
final
int
nameIndex
;
public
ConstantPoolEntryPackage
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
PACKAGE
);
nameIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
nameIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"nameIndex"
,
nameIndex
);
}
}
public
int
getNameIndex
()
{
return
nameIndex
;
}}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInteger.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInteger.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryInteger
extends
ConstantPoolEntryPrimitive
<
Integer
>
{
public
ConstantPoolEntryInteger
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
super
(
ConstantPoolType
.
INTEGER
,
1
,
stream
,
StreamUtils
::
readInt
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryDouble.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryDouble.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryDouble
extends
ConstantPoolEntryPrimitive
<
Double
>
{
public
ConstantPoolEntryDouble
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
super
(
ConstantPoolType
.
DOUBLE
,
2
,
stream
,
StreamUtils
::
readDouble
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInterfaceMethod.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryInterfaceMethod.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryInterfaceMethod
extends
ConstantPoolEntryMember
{
public
ConstantPoolEntryInterfaceMethod
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
INTERFACE_METHOD
,
stream
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryNameAndType.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryNameAndType.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryNameAndType
extends
ConstantPoolEntry
{
private
final
int
nameIndex
;
private
final
int
descriptorIndex
;
public
ConstantPoolEntryNameAndType
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
NAME_AND_TYPE
);
nameIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
nameIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"nameIndex"
,
nameIndex
);
}
descriptorIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
descriptorIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"descriptorIndex"
,
descriptorIndex
);
}
}
public
int
getNameIndex
()
{
return
nameIndex
;
}
public
int
getDescriptorIndex
()
{
return
descriptorIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryClass.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryClass.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryClass
extends
ConstantPoolEntry
{
private
final
int
nameIndex
;
public
ConstantPoolEntryClass
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
ConstantPoolType
.
CLASS
);
nameIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
nameIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"nameIndex"
,
nameIndex
);
}
}
public
int
getNameIndex
()
{
return
nameIndex
;
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryFloat.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryFloat.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
class
ConstantPoolEntryFloat
extends
ConstantPoolEntryPrimitive
<
Float
>
{
public
ConstantPoolEntryFloat
(
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
{
super
(
ConstantPoolType
.
FLOAT
,
1
,
stream
,
StreamUtils
::
readFloat
);
}
}
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMember.java
Assignment 2/src/main/ca/bcit/comp2526/constantpool/ConstantPoolEntryMember.java
package
ca
.
bcit
.
comp2526
.
constantpool
;
import
ca
.
bcit
.
comp2526
.
InvalidConstantPoolIndexException
;
import
ca
.
bcit
.
comp2526
.
NotEnoughDataException
;
import
ca
.
bcit
.
comp2526
.
StreamUtils
;
import
java
.
io
.
DataInputStream
;
import
java
.
io
.
IOException
;
public
abstract
class
ConstantPoolEntryMember
extends
ConstantPoolEntry
{
private
final
int
classIndex
;
private
final
int
nameAndTypeIndex
;
public
ConstantPoolEntryMember
(
final
ConstantPoolType
type
,
final
DataInputStream
stream
)
throws
IOException
,
NotEnoughDataException
,
InvalidConstantPoolIndexException
{
super
(
type
);
classIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
classIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"classIndex"
,
classIndex
);
}
nameAndTypeIndex
=
StreamUtils
.
readUnsignedShort
(
stream
);
if
(
nameAndTypeIndex
==
0
)
{
throw
new
InvalidConstantPoolIndexException
(
"nameAndTypeIndex"
,
nameAndTypeIndex
);
}
}
public
int
getClassIndex
()
{
return
classIndex
;
}
public
int
getNameAndTypeIndex
()
{
return
nameAndTypeIndex
;
}
}