
/*
//////////////////////////////////////////////////////
//////                misc3.c                     //////
//////////////////////////////////////////////////////

*/


/*
/////////////////////////////
//
// Author: Gayatri Krishnan
// Assignment # 8
// Internet Applications
// 
/////////////////////////////
*/


/*
////
// include files
////
*/

#include "common.h"

/* 
 ** Function    : read_attributes()
 ** Description : Outputs attributes within every method 
 */ 
void read_attributes(int totala)
{
  int status;
  int attribute_length, opcode_count, index, ldc_len;
  int temp_cIndex=0, temp_nIndex=0, temp_ntIndex=0, temp_cName=0, fFlag=0; 
  int opcodes, prev=0, prevToPrev=0;
  unsigned short spl_num1;
  unsigned short negative,big, neg8, big8;
  unsigned long neg32, big32;
  int spl_num, ret_val;
  int swit[16];
  int switch_index, byte_index, counter;
  int attr_counter;

  neg32 = 0x80000000U;
  big32 = 0xFFFFFFFFU;
  negative = 0x4000U;
  big = 0xFFFFU;
  neg8 = 0x80U;
  big8 = 0xFFU;

  /* totala Total Attributes */
  for(attr_counter=0; attr_counter< totala ;attr_counter++) {
    /* Attribute Name */
    status = read_bytes(2);
    if (status==-1) exit(0);

    if (! strcmp (cPool[((byte[0] <<8) | byte[1])].str, "Exceptions")) {
      status = read_bytes(6);
      if (status==-1) exit(0);
      if (((byte[4] <<8) | byte[5]) > 0) {
	status = read_bytes(2*((byte[4] <<8) | byte[5]));
	if (status==-1) exit(0);
      }
    }/* exceptions */

    else if (! strcmp (cPool[((byte[0] <<8) | byte[1])].str, "Code")) {
      status = read_bytes(4);
      if (status==-1) exit(0);
      /**********Attribute Length **********/
      attribute_length = (byte[0]<<24) | (byte[1]<<16) | (byte[2] <<8)| byte[3];
      /*Attribbutes*/
    
      status =read_bytes(8);
      if (status==-1) exit(0);
	
      opcodes = (byte[4]<<24) | (byte[5]<<16) | (byte[6] <<8)| byte[7];
     
      /*printf ("Number of opcodes in this method = %d\n", opcodes);*/

      for(opcode_count=0; opcode_count<opcodes; opcode_count++) {
	status =read_bytes(1);
	if (status==-1) exit(0);
	/* gets the opcode and related information ina structure */
	gotoNif = (struct sp_opcodes *) print_opcodes(1, opcode_count);
	status =read_bytes(gotoNif->attr);
	if (status==-1) exit(0);
	prevToPrev = prev;
	switch (gotoNif->attr) {
	
	case 2:
	  {
	    spl_num1 = ((byte[0] <<8) | byte[1]);
	    if ((spl_num1 & negative) !=0)
	      spl_num = opcode_count - (big -spl_num1+1);
	    else
	      spl_num = spl_num1 + opcode_count;
	    break;
	  }
	case 4:
	  {
	    spl_num1 = ((byte[0]<<24) | (byte[1]<<16) | (byte[2] <<8)| byte[3]);
	    if ((spl_num1 & neg32) !=0)
	      spl_num = opcode_count - (big32 -spl_num1+1);
	    else
	      spl_num = spl_num1 + opcode_count;
	    break;
	  }
	default :
	  break;
	}

	/* checks for special cases */
	ret_val = isSpecial();
	if (ret_val == 1)
	  printf (" %d", spl_num);
      
	else if (! strcmp (gotoNif->op_name,"sipush")) {
	  spl_num1 = ((byte[0] <<8) | byte[1]);
	  if ((spl_num1 & negative) !=0)
	    spl_num = (big -spl_num1+1);
	  else
	    spl_num = spl_num1;
	  printf (" %d", spl_num);
	}

	else if (! strcmp (gotoNif->op_name,"bipush")) {
	  spl_num1 = byte[0];
	  if ((spl_num1 & neg8) !=0)
	    spl_num = (big8 -spl_num1+1);
	  else
	    spl_num = spl_num1;
	  printf (" %d", spl_num);
	}
      
	else if ((! strcmp (gotoNif->op_name,"istore")) 
		 || (! strcmp (gotoNif->op_name,"iload"))
		 || (! strcmp (gotoNif->op_name,"aload")) 
		 || (! strcmp (gotoNif->op_name,"dload")))
	  printf (" %d", byte[0]);

	else if ( (! strcmp (gotoNif->op_name,"anewarray" )) 
		  || (! strcmp (gotoNif->op_name,"new_quick")) 
		  || (! strcmp (gotoNif->op_name,"new")) 
		  || (! strcmp (gotoNif->op_name,"anewarray_quick")) ){
	  index = cPool[spl_num1].nIndex;
	  printf(" #%d <Class %s>", spl_num1, cPool[index].str);
	}

	else if (! strcmp (gotoNif->op_name,"iinc")) {
	  spl_num1 = byte[1];
	  if ((spl_num1 & neg8) !=0)
	    spl_num = (big8 -spl_num1+1);
	  else
	    spl_num = spl_num1;
	  printf (" %d %d" , byte[0], spl_num);
	}

	else if (! strcmp (gotoNif->op_name,"ldc1")) {
	  index = cPool[byte[0]].strIndex;
	  ldc_len = cPool[index].len;
	  if (ldc_len  == 0)
	  printf(" #%d <String ' '>", byte[0]);
	else if (ldc_len > 0)
	  printf(" #%d <String '%s'>", byte[0], cPool[index].str);
	}
      
	else if (! strcmp (gotoNif->op_name,"ldc2")) {
	  index = cPool[spl_num1].nIndex;
	  printf("# %d <String '%s'", byte[0], cPool[cPool[index].nIndex].str);
	}
      
	else if (! strcmp (gotoNif->op_name,"tableswitch")) {
	  for (switch_index=0; switch_index< gotoNif->attr+1; switch_index++)
	    swit[switch_index] = byte[switch_index];
	  for (switch_index=3; switch_index<8; switch_index++) {
	    if (swit[switch_index] !=0) {
	      printf (" %d to %d: ", swit[switch_index+4], swit[switch_index+8]);
	      printf ( "default=%d\n", byte[switch_index]+opcode_count);
	      read_bytes(((swit[switch_index+8]-swit[switch_index+4])*4)+1);
	      for (byte_index = 0, counter =0; byte_index < ((swit[switch_index+8]-swit[switch_index+4])*4)+1; byte_index+=4, counter++)
		printf("\t\t%d: %d\n", counter, byte[byte_index]+opcode_count);
	      opcode_count+=(((swit[switch_index+8]-swit[switch_index+4])*4)+1);
	    }/* if */
	  }/* for */
	}/* else if */
	
	/* not implemented
	   else if (! strcmp (gotoNif->op_name,"lookupswitch")) {
	   */
	
	/* if not one of the above special cases */
	else { 
	  
	  if (gotoNif->attr > 1) {
	    
	    if (gotoNif->attr == 3) {
	      printf ( " # %d dim ", byte[1]);
	    }
	    
	    if ((cPool[byte[1]].cIndex) 
		|| (cPool[byte[1]].ntIndex) 
		|| (cPool[byte[1]].nIndex)) {
	      temp_cIndex = cPool[((byte[0] <<8) | byte[1])].cIndex;
	      temp_ntIndex = cPool[((byte[0] <<8) | byte[1])].ntIndex;
	      fFlag = cPool[((byte[0] <<8) | byte[1])].fieldFlag;
	      if (cPool[((byte[0] <<8) | byte[1])].nIndex)
		temp_cName = cPool[((byte[0] <<8) | byte[1])].nIndex;
	      
	      if (cPool[temp_cIndex].len != 0) {
		printf ("The string contains data \n");
	      }
	      
	      else {
		temp_nIndex = cPool[temp_cIndex].nIndex;
		if (cPool[temp_nIndex].len != 0);
	      }
	      
	      if (cPool[temp_ntIndex].len != 0)  {
		if (gotoNif->attr == 2){ 
		  if (fFlag == 2)
		    printf(" # %d <Field %s.%s>",byte[1], ((cPool[temp_nIndex].str="") ? "Troy":cPool[temp_nIndex].str), cPool[temp_ntIndex].str );
		  if (fFlag == 1) 
		    printf(" # %d <Method %s.%s>",byte[1], cPool[temp_nIndex].str, cPool[temp_ntIndex].str );
		}
		
	      }
	      else {
		temp_ntIndex = cPool[temp_ntIndex].nIndex;
		if (cPool[temp_ntIndex].len != 0) {
		  if (gotoNif->attr == 2){ 
		    if (fFlag == 2)
		      printf(" # %d <Field %s.%s>",byte[1], ((cPool[temp_nIndex].str="") ? "Troy" : cPool[temp_nIndex].str), cPool[temp_ntIndex].str );
		    if (fFlag == 1) 
		      printf(" # %d <Method %s.%s>",byte[1], cPool[temp_nIndex].str, cPool[temp_ntIndex].str );
		  }
		}
	      }/* else */
	    } /* if */
	    
	    if (gotoNif->attr == 3) {
	      if (cPool[temp_cName].len != 0)   
		printf(" # 2 <Class %s>",cPool[temp_cName].str);
	    }
	  } /* if (gotoNif->attr > 1) */
	}/* else goto*/
	printf("\n");
	opcode_count+=gotoNif->attr;
	prev = gotoNif->op_num;
      } /* for (opcode_count =0) */
      
      for (;opcode_count < (attribute_length -8); opcode_count++) {
	status =read_bytes(1);
	if (status==-1) exit(0);
      } /* for */
    }  /*Code */
  } /* for attr_counter */
}













