javaclass.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:7k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /***************************************
  2.   $Header: /home/amb/wwwoffle/RCS/javaclass.c 1.5 1999/02/19 19:55:09 amb Exp $
  3.   WWWOFFLE - World Wide Web Offline Explorer - Version 2.4c.
  4.   Inspect a .class Object and look for other Objects.
  5.   ******************/ /******************
  6.   Written by W. Pfannenmueller
  7.   This file Copyright 1998,99 W. Pfannenmueller
  8.   It may be distributed under the GNU Public License, version 2, or
  9.   any higher version.  See section COPYING of the GNU Public license
  10.   for conditions under which this file may be redistributed.
  11.   ***************************************/
  12. #define DEBUG_HTML 0
  13. /*
  14. #ifndef DEBUG
  15. #define DEBUG
  16. #endif
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <unistd.h>
  23. #include "wwwoffle.h"
  24. #include "document.h"
  25. #include "misc.h"
  26. #include "errors.h"
  27. typedef unsigned char Byte;
  28. typedef unsigned long Int;
  29. typedef unsigned int Short;
  30. static Int getInt(int fd);
  31. static Short getShort(int fd);
  32. static Byte getByte(int fd);
  33. static int readCONSTANTS(int fd);
  34. static int isStandardClass(char *className);
  35. static char *className;
  36. static int read_byte(int fd);
  37. static char *readUtf8(int fd); 
  38. static char *readUnicode(int fd); 
  39. static char *addclass(char *name);
  40. static struct CONSTANTS
  41. {
  42.     Byte type;
  43.     Byte isClassName;
  44.     char *name;
  45. } *constants;
  46. static const char class[] = ".class";
  47. static const char *standardClasses[] = {"java/", "javax/", 
  48.                 /* add more standard packages if necessary */ };
  49. /*++++++++++++++++++++++++++++++++++++++
  50.   Look for referenced classes 
  51.   int InspectJavaClass Returns 1 if it is a valid class File and
  52.                                  other class References have been found,
  53.                                0 if not.
  54.   ++++++++++++++++++++++++++++++++++++++*/
  55. int InspectJavaClass(int fd,URL *Url)
  56. {
  57.  PrintMessage(Debug,"Parsing document using JavaClass parser.");
  58.     className = Url->name;
  59.     #ifdef DEBUG
  60.     PrintMessage(Debug,"InspectClass %s",className);
  61.     #endif
  62.     /* test for valid class file */
  63.     if(getInt(fd) == 0xcafebabeL)
  64.     {
  65.         /* Subversionsnummer */
  66.         getShort(fd);
  67.         /* Versionsnummer: */
  68.         getShort(fd);
  69.         /* now read all Constants including class names */    
  70.         return readCONSTANTS(fd);
  71.     }
  72.     #ifdef DEBUG
  73.     PrintMessage(Debug,"No Java Bytecode");
  74.     #endif
  75.     return 0;
  76. }            
  77. Int getInt(int fd)
  78. {
  79.      return 
  80.           read_byte(fd) * 256 * 256 * 256 +
  81.           read_byte(fd) * 256 * 256 +
  82.           read_byte(fd) * 256 +
  83.           read_byte(fd);
  84. }
  85. Short getShort(int fd)
  86. {
  87.      return 
  88.           read_byte(fd) * 256 +
  89.           read_byte(fd);
  90. }
  91. Byte getByte(int fd)
  92. {
  93.      return 
  94.           read_byte(fd);
  95. }
  96. #define CONSTANT_Utf8 1 
  97. #define CONSTANT_Unicode 2 
  98. #define CONSTANT_Integer 3 
  99. #define CONSTANT_Float 4 
  100. #define CONSTANT_Long 5 
  101. #define CONSTANT_Double 6 
  102. #define CONSTANT_Class 7 
  103. #define CONSTANT_String 8 
  104. #define CONSTANT_Fieldref 9 
  105. #define CONSTANT_Methodref 10 
  106. #define CONSTANT_InterfaceMethodref 11 
  107. #define CONSTANT_NameAndType 12 
  108. char *readUtf8(int fd) 
  109. {
  110.     char *ret;
  111.     Short i;
  112.     Short len = getShort(fd);
  113.     ret = (char *)malloc(len + sizeof(''));
  114.     for(i = 0; i < len; i++)
  115.     {
  116.         ret[i] = (char)getByte(fd);
  117.     }
  118.     ret[i] = '';    
  119.     return ret;
  120. }
  121. static unsigned char *UnicodeToUTF8(unsigned char *uni,int len)
  122. {
  123.     int i,j;
  124.     unsigned char *ret = (char *)malloc(3 * len + 1);
  125.     for(i = 0, j = 0; i < len*2; i+= 2,j++)
  126.     {
  127.         /* 1 byte */
  128.         if(uni[i] == 0 && !(uni[i+1] & 0x80) && uni[i+1])
  129.         {
  130. ret[j] = uni[i+1];
  131.         }
  132.         /* 2 bytes */
  133.         else if(!(uni[i] & ~0x07)) 
  134.         {
  135.             ret[j] = 0xC0 | (uni[i] << 2) | (uni[i+1] >> 6); 
  136.             ret[j+1] = 0xBF & (0x80 | uni[i+1]);
  137.             j++;
  138.         }
  139.         /* 3 bytes */
  140.         else 
  141.         {
  142.             ret[j] = 0xE0 | (uni[i] >> 4);
  143.             ret[j+1] = 0xBF & (0x80 | (uni[i] << 2) | (uni[i+1] >> 6)); 
  144.             ret[j+2] = 0xBF & (0x80 | uni[i+1]);
  145.             j += 2;
  146.         }
  147.     }
  148.     free(uni);
  149.     return ret;
  150. }
  151. char *readUnicode(int fd) 
  152. {
  153.     Short i;
  154.     Short len = getShort(fd);
  155.     char *ret = (char *)malloc(len);
  156.     for(i = 0; i < len; i++)
  157.     {
  158.         ret[i] = getByte(fd);
  159.     }
  160.     return UnicodeToUTF8(ret,len);
  161. }
  162. int readCONSTANTS(int fd)
  163. {
  164.     int ret = 0;
  165.     int i;
  166.     Short s;
  167.     int nclasses = 0;
  168.     /* Anzahl Konstanten - 1 */
  169.     Short nconstants = getShort(fd); 
  170.     constants = 
  171.         (struct CONSTANTS *)malloc(sizeof(struct CONSTANTS) * nconstants);
  172.     memset(constants,'',sizeof(struct CONSTANTS) * nconstants);
  173.     for(i = 1; i < nconstants; i++)
  174.     {
  175.         Byte b = getByte(fd);
  176.         constants[i].type = b;
  177.         switch(b)
  178.         {
  179.             case CONSTANT_Utf8:
  180.                 constants[i].name = readUtf8(fd);
  181.                 break;
  182.             case CONSTANT_Unicode:
  183.                 constants[i].name = readUnicode(fd);
  184.                 break;
  185.             case CONSTANT_Integer: 
  186.             case CONSTANT_Float: 
  187.                 getInt(fd);
  188.                 break;
  189.             case CONSTANT_Long: 
  190.             case CONSTANT_Double: 
  191.                 getInt(fd);
  192.                 getInt(fd);
  193.                 i++;
  194.                 break;
  195.             case CONSTANT_Class: 
  196.                 s = getShort(fd);
  197.                 constants[s].isClassName = 1;
  198.                 nclasses++; 
  199.                 break;
  200.             case CONSTANT_String: 
  201.                 getShort(fd);
  202.                 break;
  203.             case CONSTANT_Methodref: 
  204.             case CONSTANT_Fieldref: 
  205.             case CONSTANT_InterfaceMethodref: 
  206.             case CONSTANT_NameAndType: 
  207.                 getShort(fd);
  208.                 getShort(fd);
  209.                 break;
  210.             default:
  211.                 #ifdef DEBUG
  212.                 PrintMessage(Debug,"unknown CONSTANT type: %d",b);
  213.                 #endif
  214.                 #if DEBUG_HTML
  215.                 PrintMessage(Warning,"invalid class file "%s"",className);
  216.                 #endif
  217.                 return 0;
  218.         } 
  219.     }
  220.     for(i = 0; i < nconstants; i++)
  221.     {
  222.         char *name = constants[i].name;
  223.         if(name != NULL)
  224.         {
  225.             if(constants[i].isClassName != 0 && 
  226.                !isStandardClass(name)
  227.             ) 
  228.             {
  229.                 name = addclass(name);  
  230.                 if(strstr(className,name) == NULL)
  231.                 {
  232.                     #ifdef DEBUG
  233.                     PrintMessage(Debug,"Class: %s",name);
  234.                     #endif
  235.                     AddReference(name,RefInlineObject);
  236.                     ret = 1;
  237.                 }
  238.             }
  239.             #ifdef DEBUG
  240.             else
  241.             {
  242.                 PrintMessage(Debug,"Not fetched: %s",name);
  243.             }
  244.             #endif
  245.             free(name);
  246.         }
  247.     }
  248.     return ret;
  249. }
  250. char *addclass(char *name)
  251. {
  252.     char *ret = (char *)malloc(strlen(name) + sizeof(class));
  253.     strcpy(ret,name);
  254.     strcat(ret,class);
  255.     free(name);
  256.     return ret;
  257. }
  258. int isStandardClass(char *name)
  259. {
  260.     int i;
  261.     for(i = 0; i < (sizeof(standardClasses)/sizeof(char *)); i++)
  262.     {
  263.          if(!strncmp(name,
  264.             standardClasses[i],
  265.             strlen(standardClasses[i]))
  266.          )
  267.          {
  268.             return 1;
  269.          } 
  270.     }
  271.     return 0;
  272. }
  273. int read_byte(int fd)
  274. {
  275.    unsigned char byte;
  276.    if(read_data(fd,&byte,1) != 1)
  277.    {
  278.         #if DEBUG_HTML
  279.         PrintMessage(Warning,"garbled class file "%s"",className);
  280.         #endif
  281.         return EOF;
  282.    }
  283.    return byte;
  284. }