My Java Assignment 2

profilechoks
assignment-2-solution.zip

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 < 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 < 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 < extends   Number >
     extends   ConstantPoolEntry
{
     interface   Filter < 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 ;
     }
}