
/*
//////////////////////////////////////////////////////
//////                main.c                    //////
//////////////////////////////////////////////////////
*/


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


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

#include "common.h"

/*
 ** Function : main()
 */
void main(int argc, char **argv) {

  int status;
  
  /* Checks the number of arguments in the command line */
  if (argc < MIN_NUM_ARGS) {
         printf ("Invalid Number of Arguments\n");
	 printf ("Usage: od -An -tx -w4 *.class | pars [-ALL] [-C] [-M]\n\t Note: options must be in CAPS\n");
	 exit(0);
  }

  if (!strcmp(ALL_STR, argv[1])) {
    printFlag = 1;
    all();
  }
  
  else if (!strcmp(METHOD_STR, argv[1])) {
    printFlag = 0;
    methods();
    status = read_bytes(2000);
    if (status==-1) exit(0); 
  }

  else if (!strcmp(CPOOL_STR, argv[1])) {
    printFlag = 1;
    constantPool();
    status = read_bytes(2000);
    if (status==-1) exit(0); 
  }
  
  else {
     printf ("Invalid Command\n");
     printf ("Usage: od -An -tx -w4 *.class | pars <[-ALL] [-C] [-M]> | more\n \t Note: options must be in CAPS\n");
     exit(0);
  }
}/* main */
	

/* 
 ** Function    : all()
 ** Description : Outputs Constant Pools, Fields and Methods
 */ 
void all(void) {

  int status;
  int Constant_Pool_Count;
  int interface_count, fields_count, methods_count, attributes_count;

    status=read_bytes(8);
    if (status==-1) exit(0);
    printf("**********Constant_Pool_Count**********\n");
    status = read_bytes(2);
    if (status==-1) exit(0);
    Constant_Pool_Count = byte[0] <<8 | byte[1];
    print_constants(Constant_Pool_Count);
    printf("--------------------------------------------------------------------\n");
     
    /**********access_flags**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    /**********this_class**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    /**********super_class**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    /***********interfaces_count**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    interface_count=(byte[0]<<8)|byte[1];
    if (interface_count > 0)
	read_interfaces(interface_count);


    /**********fields_count**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    fields_count=(byte[0]<<8)|byte[1];
    printf("Fields :\n");
    if (fields_count > 0)
	read_fields(fields_count);

    printf("--------------------------------------------------------------------\n");
    /***********methods_count**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    methods_count=(byte[0]<<8)|byte[1];
    if (methods_count > 0)
	read_methods(methods_count);

   
    /***********attributes_count**********/
    status = read_bytes(2);
    if (status == -1) exit(0);
    attributes_count=(byte[0]<<8)|byte[1];
    if (attributes_count > 0) {
      read_attributes(attributes_count);
    }
}

/* 
 ** Function    : methods()
 ** Description : Outputs Methods only
 */ 
void methods(void) {

  int status, counter, attr_counter;
  int attributes_count, methods_count, Constant_Pool_Count, interface_count, fields_count;
   status = read_bytes(8);
   if (status==-1) exit(0);

   /* read Constant Pool bytes */
    status = read_bytes(2);
    if (status==-1) exit(0);
    Constant_Pool_Count = byte[0] <<8 | byte[1];
    print_constants(Constant_Pool_Count);
 
    status = read_bytes(6);
    if (status == -1) exit(0);
   
    status = read_bytes(2);
    if (status == -1) exit(0);

    interface_count=(byte[0]<<8)|byte[1];
    if (interface_count > 0){
      for(counter=0; counter < interface_count ;counter++) {
	status = read_bytes(2);
	if (status == -1) exit(0);
      }
    }

    /* read Field bytes */
    status = read_bytes(2);
    if (status == -1) exit(0);
    fields_count=(byte[0]<<8)|byte[1];

    if (fields_count > 0)
    for(counter=0; counter < fields_count ;counter++) {
      status = read_bytes(8);
      if (status == -1) exit(0);

      attributes_count=(byte[6]<<8)| byte[7];
      if (attributes_count > 0){
	for(attr_counter=0; attr_counter < attributes_count; attr_counter++) {
	  status = read_bytes(8);
	  if (status == -1) exit(0);
	  }/* for */
      }/* if */
    }/* for */

    /* read methopd bytes and print */ 
    status = read_bytes(2);
    if (status == -1) exit(0);
    methods_count=(byte[0]<<8)|byte[1];
    if (methods_count > 0)
	read_methods(methods_count);

    printf("--------------------------------------------------------------------\n");
    
    status = read_bytes(2);
    if (status == -1) exit(0);
    attributes_count=(byte[0]<<8)|byte[1];

    if (attributes_count > 0) 
      read_attributes(attributes_count);
}


/* 
 ** Function    : ConstantPool()
 ** Description : Outputs Constant Pool entries
 */ 
void constantPool(void) {

  int status;
  int Constant_Pool_Count;

  status = read_bytes(8);
  if (status==-1) exit(0);

    printf("**********Constant_Pool_Count**********\n");
    status = read_bytes(2);
    if (status==-1) exit(0);
    Constant_Pool_Count = byte[0] <<8 | byte[1];
    print_constants(Constant_Pool_Count);
}

