home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / borland / ib / setups / intrabld / data.z / NETCLASS.JS < prev    next >
Text File  |  1996-12-11  |  21KB  |  562 lines

  1. /****************************************************************************\
  2. *                                                                            *
  3. * NetClass.js  -- These classes are designed to help organize the data we    *
  4. * send and receive over the internet.                                        *
  5. *                                                                            *
  6. *                                                                            *
  7. * Dependencies:  localurl.qry                                                *
  8. *                                                                            *
  9. *                                                                            *                                                                            *
  10. * Links to:                                                                  *
  11. *                                                                            *
  12. * Updated 8/21/96 by IntraBuilder Samples Group                              *
  13. * $Revision:   1.2  $                                                        *
  14. *                                                                            *
  15. * Copyright (c) 1996, Borland International, Inc. All rights reserved.       *
  16. *                                                                            *
  17. \****************************************************************************/
  18.  
  19. function loadExternalFunctions()  //call me first!!
  20. {
  21. //In order to use the net classes you must call this function.
  22. //Immediately after you call _sys.scripts.load("netclass")
  23. //call loadExternalFunctions()  
  24.  extern char* requestUrl (char* /*url*/) "reqstURL.dll";
  25.  extern char* requestHead (char* /*url*/) "reqstURL.dll";
  26.  
  27.  extern void getWebName(char*/*ip address*/,char*/*string to put name in*/)"reqsturl.dll";
  28. }
  29.  
  30.  
  31.  
  32.  
  33. class HtmlFile(input) {
  34. //This class is a wrapper for HTML files
  35.  
  36. //MEMBER VARIABLES////////////////////////////////////////////////
  37.   this.text=new String(input);  //a place to store the html text
  38.   this.baseUrl=new Url("");     //remember where it came from
  39.   this.url=new Url("");
  40.  
  41. //MEMBER FUNCTIONS/////////////////////////////////////////////////
  42.   function findBase()  {
  43.   //looks for a tag like <base href="http://www.borland.com">
  44.  
  45.     var openTagMark=0;
  46.     var closeTagMark=0;
  47.     var hrefMark=0;
  48.     var baseMark=0;
  49.     var endHeadMark=0;
  50.     var tempString=new String();
  51.     var i,k=0;
  52.     openTagMark=this.text.indexOf('<'); //find any tag between <>, eg <head>
  53.     closeTagMark=this.text.indexOf('>');
  54.     for( i=1; (openTagMark>=0 && closeTagMark>=0);i++)
  55.     {
  56.      tempString=this.text.substring(openTagMark+1,closeTagMark); //extract what is between the < > marks
  57.      tempString=tempString.toLowerCase();                        //convert that to lower case
  58.      hrefMark=tempString.indexOf("href");
  59.      endHeadMark=tempString.indexOf("/head");
  60.      if (hrefMark>0)                                        //we only want those with hrefs
  61.      {
  62.       k++; 
  63.       baseMark=tempString.indexOf("base");
  64.       if ( (baseMark>=0) && (k==1) && (baseMark<hrefMark) ){  //first href might be "base"
  65.                                                            //<BASE HREF="http://www.borland.com">
  66.                                                            //if so "BASE" must be before "HREF" 
  67.        var beginQuoteIndex=tempString.indexOf("\"",hrefMark);
  68.        var endQuoteIndex=tempString.lastIndexOf("\"");             
  69.        var tempUrl=new Url(tempString.substring(beginQuoteIndex+1,endQuoteIndex)); //extract the Url from within the quotes
  70.        this.baseUrl=tempUrl; //store the base string (ie http://www.borland.com)         
  71.        return true;
  72.       }else{
  73.        this.baseUrl=this.url;
  74.        return false;
  75.       }
  76.      }else if(endHeadMark>=0){//we've reached the end of the head element
  77.       this.baseUrl=this.url;     //base can only be specified within <head></head>
  78.       return false;
  79.      }
  80.      this.text=this.text.substring(closeTagMark+1,this.text.length); //truncate the html string
  81.      openTagMark=this.text.indexOf('<');
  82.      closeTagMark=this.text.indexOf('>');
  83.     }//end for
  84.     this.baseUrl=this.url;
  85.     return false;
  86.    }//end function
  87.  
  88.     function getReferences() 
  89.     //This function finds all references to other urls
  90.     {
  91.     var tag=new Array(0);
  92.     var openTagMark=0;
  93.     var closeTagMark=0;
  94.     var hrefMark=0;
  95.     var noHrefMark=0;
  96.     var srcMark=0;
  97.     var textInBrackets=new String();
  98.     var lcTextInBrackets=new String();
  99.     var i;
  100.      if (this.findBase()==false && this.baseUrl.text.length==0) { //we must make sure that either
  101.                                                              // 1. the document contains a <base href="www.x.com">
  102.       return;                                                // 2. we have stored the url where the document came from
  103.      }
  104.      openTagMark=this.text.indexOf('<');               //find <> marks
  105.      closeTagMark=this.text.indexOf('>');
  106.     for( i=1; (openTagMark>=0 && closeTagMark>=0);i++)
  107.     {
  108.      badProtocol=false;
  109.      textInBrackets=this.text.substring(openTagMark+1,closeTagMark); //extract what is between the < > marks
  110.      lcTextInBrackets=textInBrackets.toLowerCase();                   //convert that to lower case
  111.  
  112.  
  113.         srcMark=lcTextInBrackets.indexOf("src");
  114.         hrefMark=lcTextInBrackets.indexOf("href");
  115.         noHrefMark=lcTextInBrackets.indexOf("nohref");
  116.         if (hrefMark>=0 && noHrefMark<0)                     //we only want those with hrefs
  117.         {
  118.          if(lcTextInBrackets.indexOf("mailto:")<0 && lcTextInBrackets.indexOf("#")<0){ //no mailto or local links 
  119.           tag.add(this.extractLink(textInBrackets,hrefMark)); //add the link to our tag array
  120.          }
  121.         }else if( srcMark>0){ //we're looking for something like <img src="picture.gif">
  122.           tag.add(this.extractLink(textInBrackets,srcMark)); //add frame references to our array
  123.         }
  124.  
  125.      this.text=this.text.substring(closeTagMark+1,this.text.length); //truncate the html string
  126.      openTagMark=this.text.indexOf('<');                                         //find the next <A href="">
  127.      closeTagMark=this.text.indexOf('>');                                        // and move on
  128.     }//end for
  129.     return tag;
  130.  }//end  getReferences()
  131.  
  132.  function extractLink(text,mark){
  133.        text=charReplace(text,'\'','\"'); //change all ' to "
  134.        var openQuote=text.indexOf("\"",mark); //find first quote after 'href='
  135.        var closeQuote=text.indexOf("\"",openQuote+1); //find second quote
  136.        var refIndex;
  137.        var fullUrl="";
  138.        if (openQuote<0 || closeQuote<0){
  139.         return "";
  140.        }
  141.  
  142.        var quotedText=new StringEx(text.substring(openQuote+1,closeQuote)); //extract the string between quotes
  143.        quotedText=stripSpace(quotedText);                                   //remove any garbage white space
  144.  
  145.        var lcQuotedText=quotedText.toLowerCase();      //use lower case version for comparison
  146.  
  147.        //Let's convert all refs of the form "http:/index.html" to "/index.html"
  148.        if(lcQuotedText.indexOf("http:")==0 && lcQuotedText.indexOf("http://")<0){
  149.         quotedText=quotedText.substring(5,quotedText.length);
  150.        }
  151.  
  152.        if (quotedText.charAt(0)=='/'){  //this is a relative url
  153.          fullUrl=this.baseUrl.base + quotedText;  //make it absolute by adding base
  154.        }else if (quotedText.indexOf("://")>0){ //absolute url
  155.          fullUrl= quotedText;                     //just add it to array
  156.        }else {  //relative url without the "/" to start with (this is bad form but people do use it).
  157.          fullUrl=this.baseUrl.baseDir +"/"+quotedText;
  158.        }//endif
  159.         return fullUrl;
  160.  
  161.  }//end function extractLink
  162.  
  163. }//end class
  164.  
  165. class HeaderFile(info)
  166. {//Pass this class an http header and it will tell you all kinds
  167.  //of good information.
  168.  
  169. //MEMBER VARIABLES////////////////////////////////////////////////
  170.  
  171.   this.text=new StringEx(info.toLowerCase());
  172.  
  173.     this.dateIndex=0;
  174.     this.serverIndex=0;
  175.     this.contentTypeIndex=0;
  176.     this.lastModIndex=0;
  177.     this.contentLengthIndex=0;
  178.     this.returnCodeIndex=0;
  179.     this.date="";
  180.     this.server=""; 
  181.     this.contentType=""; 
  182.     this.lastModified="";
  183.     this.contentLength="";
  184.     this.returnCode="";
  185.  
  186.  this.nToR();
  187.  this.parse();
  188.  
  189. //MEMBER FUNCTIONS/////////////////////////////////////////////////
  190.  function parse(){
  191.  //parses the header file
  192.     with (this){
  193.         dateIndex= text.indexOf("date:");       
  194.         serverIndex=text.indexOf("server:");
  195.         contentTypeIndex=text.indexOf("content-type:");
  196.         lastModIndex=text.indexOf("last-modified:");
  197.         contentLengthIndex=text.indexOf("content-length:");
  198.         returnCodeIndex=text.indexOf("http/1.0");
  199.     }//end with
  200.  
  201.     this.text=this.text+'\r'; //add a \r to the end to make parsing easier
  202.     var endOfLineIndex=0;
  203.     if(this.returnCodeIndex<0){
  204.         this.returnCode ="err unable to retrieve file"; //if we don't even get a code, we must have timed out.
  205.         return;                                         //no need to parse because we didn't get any text
  206.     }else{
  207.         endOfLineIndex=this.text.indexOf("\r",this.returnCodeIndex+1);
  208.         this.returnCode= this.text.substring(this.returnCodeIndex+8,endOfLineIndex);
  209.     }
  210.  
  211.     endOfLineIndex=this.text.indexOf("\r",this.serverIndex+1);
  212.     if (this.serverIndex>=0){//server name is specified
  213.      this.server= this.text.substring(this.serverIndex+7,endOfLineIndex);
  214.     }else{
  215.      this.server="not available: may be password protected"
  216.     }
  217.  
  218.     endOfLineIndex=this.text.indexOf("\r",this.dateIndex+1);
  219.     if (this.dateIndex>=0){ //date is specified
  220.      this.date=this.text.substring(this.dateIndex+5,endOfLineIndex);
  221.     }else{
  222.      this.date="not available"
  223.     }
  224.  
  225.     endOfLineIndex=this.text.indexOf("\r",this.contentTypeIndex+1);
  226.     if (this.contentTypeIndex>=0){
  227.       this.contentType=this.text.substring(this.contentTypeIndex+13,endOfLineIndex);
  228.     }else{
  229.       this.contentType="not available";
  230.     }
  231.  
  232.     endOfLineIndex=this.text.indexOf("\r",this.lastModIndex+1);
  233.     if (this.lastModIndex>=0){
  234.        this.lastModified=this.text.substring(this.lastModIndex+14,endOfLineIndex);
  235.     }else{
  236.        this.lastModified="not available";
  237.     }
  238.  
  239.     endOfLineIndex=this.text.indexOf("\r",this.contentLengthIndex+1);
  240.     if (this.contentLengthIndex>=0){
  241.       this.contentLength=this.text.substring(this.contentLengthIndex+15,endOfLineIndex);
  242.     }else{
  243.       this.contentLength="not available";
  244.     }
  245.  
  246.     //remove the \r we added earlier
  247.     this.text=this.text.substring( 0,this.text.length-1 )
  248.  
  249.  }//end parse()
  250.  
  251.   function nToR(){
  252.   //converts all \n to \r
  253.   //This makes it easier to parse later.
  254.    var newLinePos=this.text.indexOf('\n');
  255.    while(newLinePos>=0){
  256.      this.text=new StringEx(this.text.stuff(newLinePos,1,'\r'));
  257.      newLinePos= this.text.indexOf('\n');
  258.    }
  259.    return
  260.   }//end nToR
  261.  
  262. }//end HeaderFile class
  263.  
  264.  
  265.  
  266. class HttpResponse(url){
  267.   
  268. //This class retreives both the header and the html text for a Url
  269. //Pass it a Url object and it takes care of the rest.
  270.  
  271. //MEMBER VARIABLES////////////////////////////////////////////////
  272.  this.header=new HeaderFile("");
  273.  this.html=new HtmlFile("");
  274.  this.text=requestUrl(url.text);
  275.  var textToProcess=this.text
  276.  this.parse(textToProcess);//fill header and html with proper info.
  277.  this.html.url=url;
  278.  this.html.findBase();
  279.  
  280. //MEMBER FUNCTIONS////////////////////////////////////////////////
  281.   function parse(input){
  282.      var testString=new StringEx(input);
  283.      var emptyLineIndex=0;
  284.      emptyLineIndex=this.findBlankLine(input);//look for blank line
  285.      testString=input.substring(0,emptyLineIndex);
  286.      this.header=new HeaderFile(input.substring(0,emptyLineIndex));
  287.      this.html= new HtmlFile(input.substring(emptyLineIndex+1,input.length));
  288.   }// end parse()
  289.  
  290.   function findBlankLine(input){
  291.   //look for /n/n or /r/n/r/n or /r/r
  292.    var Key=new Array(4);
  293.  
  294.     Key[0]=input.indexOf("\r\r");
  295.     Key[1]=input.indexOf("\r\n\r");
  296.     Key[2]=input.indexOf("\n\r\n");
  297.     Key[3]=input.indexOf("\n\n");
  298.  
  299.     Key.sort(0);
  300.     for (i=0;i<Key.length;i++){
  301.      if (Key[i]>0){ //first key>0 is the first blank line.
  302.       return Key[i];
  303.      }
  304.     }
  305.  
  306.     return -1;
  307.   }
  308.    
  309.  }//end HttpResponse
  310.  
  311. class HeadResponse(url)
  312. {
  313. //This class retrieves and stores header information for a URL
  314. //Pass it a Url object and it does the rest.
  315.  //MEMBER VARIABLES//////////////////////////////////////////////////////////// 
  316.  this.url=url
  317.  this.text=requestHead(url.text);
  318.  var textToProcess=this.text;
  319.  this.headerFile=new HeaderFile(textToProcess);
  320.  
  321. }//end HeadResponse
  322.  
  323. class IpAddress(addressText)
  324. {
  325. //This class is a wrapper for numeric ip addresses
  326.  
  327.   //MEMBER VARIABLES////////////////////////////////////////////////////////////
  328.   this.text=new String(addressText);
  329.   this.name="                                      ";
  330.   this.isValid=this.checkValidity();
  331.  
  332.  
  333.  //MEMBER FUNCTIONS////////////////////////////////////////////////////////////
  334.  function checkValidity(){
  335.  //We are looking for something like 255.254.253.252
  336.  //There should be 3 periods separating 4 numbers.
  337.  
  338.   var charNum=0;
  339.   var startingChar=0;
  340.   var count=0;
  341.   //look for 3 periods seperated by at least one character
  342.       while(charNum>-1){
  343.        charNum=this.text.indexOf(".",startingChar);
  344.        startingChar=charNum+2;//look for the next period two characters from where we found the first
  345.           if(charNum>=0){
  346.            count++;
  347.           }//endif
  348.       }//endwhile
  349.   if (count!=3){
  350.    return false;
  351.   }
  352.   //Ok it has 3 periods in it,
  353.   //now make sure each section is a number between 0 and 255
  354.   var section=new Array(4);
  355.   section=this.parse();
  356.  
  357.   for (i=0;i<section.length;i++){ //put each section through 3 tests
  358.  
  359.        if(section[i].indexOf(":") > 0){ // Strip off port number if exists
  360.         section[i]=section[i].substring(0,section[i].indexOf(":"));
  361.        }
  362.        if(section[i].length >3){  //check to make sure each section is only 3 characters
  363.         return false;
  364.        }//endif 
  365.  
  366.        if (parseInt(section[i])<0 || parseInt(section[i])>255){ //check that numeric value is in proper range
  367.         return false;
  368.        }//endif
  369.  
  370.        var tempString=new StringEx(section[i]);     
  371.  
  372.        while(tempString.length>0){      
  373.         if (tempString.isAlpha()){ //check that there are no alphabetical characters in the string.
  374.          return false;                  
  375.         }//end if
  376.         tempString=new StringEx(tempString.substring(1,tempString.length)); //chop off first character
  377.        }//end while       
  378.         
  379.    }//end for
  380.   //passed all the tests
  381.   return true;
  382.   }//end isValid()
  383.   function parse(){
  384.       var byteValue=new Array(4);
  385.       var period =new Array(4);
  386.       with(this){
  387.        period[0]=text.indexOf(".");
  388.        period[1]=text.indexOf(".",period[0]+1);
  389.        period[2]=text.indexOf(".",period[1]+1);
  390.        byteValue[0]=text.substring(0,period[0]);
  391.        byteValue[1]=text.substring(period[0]+1, period[1]);
  392.        byteValue[2]=text.substring(period[1]+1, period[2]);
  393.        byteValue[3]=text.substring(period[2]+1, text.length);
  394.       }
  395.     return byteValue;
  396.     }
  397.     function toDecimal(){
  398.     //calculates the numeric value of an ip address
  399.       var bytes=new Array(4);
  400.       bytes=this.parse();
  401.       var total=0;
  402.       var temp=0;
  403.       for (i=0;i<bytes.length;i++){
  404.        total+=parseInt(bytes[i])*Math.pow(256,3-i)
  405.       }
  406.       return total;
  407.     }//end toDecimal
  408.  
  409.     function decimalToIp(number){
  410.     //converts a number to an IP address.
  411.        var num=number;
  412.        var bytes=new Array(4);
  413.        var i=0;
  414.        this.text="";
  415.        for (i=(bytes.length-1);i>=0;i--){
  416.           bytes[i]=Math.int(num%256);
  417.           num=Math.int(num/256);
  418.        }//endfor
  419.        for (i=0;i<bytes.length;i++){
  420.            this.text+=(""+bytes[i]);
  421.            if(i!=3){
  422.             this.text+="."; //we only need 3 periods when i=0,1 or 2
  423.            }//endif
  424.        }//endfor
  425.       return;
  426.     }//end decimalToIP();
  427.  
  428.     function getName(){
  429.      var temp=new StringEx().space(75) ;
  430.      getWebName(this.text,temp);   
  431.      this.name=temp;
  432.      return this.name;
  433.     }
  434.  }//end class IpAddress
  435.  
  436.  class Url (input)
  437. {//This class is a wrapper for Url's
  438.  //pass it a string of the form http://www.borland.com/tributeToElvis.html
  439.  //to initialize it.
  440.  
  441.  this.text=input;
  442.  this.protocol="";
  443.  this.protIndex=0;
  444.  this.host="";
  445.  this.hostIndex=0;
  446.  this.fileName="";
  447.  this.fileIndex=0;
  448.  this.extension=""
  449.  this.extensionIndex=0;
  450.  this.isValid=true;
  451.  this.base="";
  452.  this.baseDir="";
  453.  this.port=80;
  454.  
  455.  this.parse(); //parse it
  456.  
  457.  //store these items in lower case
  458.  this.host=this.host.toLowerCase();
  459.  this.protocol=this.protocol.toLowerCase();
  460.  this.extension=this.extension.toLowerCase();
  461.  
  462.  function parse(){
  463.  //extracts host, filename, protocol, base, and basedir from text.
  464.  var i=0;
  465.  var extensionEnd=-1;
  466.  
  467.   with (this){
  468.     protIndex=text.indexOf('://');
  469.     hostIndex=text.indexOf('/',protIndex+3);
  470.     protocol= text.substring(0,protIndex);                 //http
  471.     host= text.substring(protIndex+3, hostIndex);          //www.borland.com
  472.     fileName= text.substring(hostIndex,text.length);//     /index.html
  473.     baseDir=text.substring(0,text.lastIndexOf("/") );
  474.     base=text.substring(0,hostIndex);    
  475.    }//end with (this)
  476.  
  477.     if (this.protIndex<0 || this.hostIndex<0 || this.fileName.length==0){
  478.      this.isValid=false;
  479.      return;
  480.     }
  481.  
  482.  
  483.     var portIndex= this.host.indexOf(":");
  484.     if (portIndex>0){
  485.      this.port=parseInt(this.host.substring(portIndex+1,this.host.length));   //extract the port number
  486.      this.host=this.host.substring(0,portIndex);               //truncate the host string to www.anycorp.com
  487.     }
  488.      var periodIndex=this.fileName.lastIndexOf("."); //find where the extension begins
  489.      if(periodIndex<0){  //no extension
  490.        this.extension="";
  491.        return;
  492.      }
  493.  
  494.                                                                        //To find extension
  495.      this.extension=this.fileName.substring(periodIndex+1,this.text.length); //extract everything beyond the period in the filename
  496.      var endIndex=new Array(2);
  497.      endIndex[0]= this.extension.indexOf("?"); //check to see if the file is being fed arguemnets (eg /file.exe?var=fred or /file.exe/var=fred)
  498.      endIndex[1]= this.extension.indexOf("/");
  499.      endIndex.sort();
  500.      //we need to choose the smallest endIndex value greater than zero.
  501.      //The next loops finds that.
  502.      for (i=0;i<endIndex.length;i++){
  503.       if (endIndex[i]>=0){
  504.        extensionEnd=endIndex[i]
  505.         }
  506.      }
  507.      
  508.      if (extensionEnd>=0){                                           //if file is being fed arguments
  509.       this.extension=this.extension.substring(0,extensionEnd); //just extract extension and throw away the arguements
  510.      }
  511.       
  512.     this.relativeToAbs();//convert filename from relative to absolute
  513.     return
  514.  }//end parse()
  515.  
  516.   function relativeToAbs(){
  517.   //converts path navigation marks (..) within a baseDir to an absolute path.
  518.  
  519.     var doubleDotsIndex = this.fileName.indexOf(".."); //look for relative path
  520.   //If the filename starts with a .., just remove the ... There is no way to move
  521.   //up a directory from the root dir.
  522.     while(doubleDotsIndex==0){
  523.      this.filename=this.fileName.substring(2,this.fileName.length);
  524.      doubleDotsIndex=this.fileName.indexOf("..");
  525.     }
  526.  
  527.     while (doubleDotsIndex>0){
  528.      var prevDirIndex=this.fileName.lastIndexOf("/",doubleDotsIndex-2);
  529.      var part1= this.fileName.substring(0,prevDirIndex)
  530.      var part2= this.fileName.substring(doubleDotsIndex + 2,this.fileName.length);
  531.      this.fileName=part1+part2;
  532.      doubleDotsIndex=this.fileName.indexOf("..");
  533.     }//end while
  534.     this.text=this.base+this.fileName
  535.    }//end relativeToAbs()
  536.  
  537. }//end Url class
  538.  
  539.   function charReplace(text,charOld,charNew){
  540.   //Pass a string with charOld in it and
  541.   //this function converts all charOld to charNew
  542.    var tempText=new StringEx(text);
  543.    var charOldPos=tempText.indexOf(charOld);
  544.    while(charOldPos>=0){
  545.      tempText=new StringEx(tempText.stuff(charOldPos,1,charNew));
  546.      charOldPos=tempText.indexOf(charOld);
  547.    }
  548.    return  tempText;
  549.   }//end nToR
  550.  
  551.   function stripSpace(text){
  552.   //removes all leading white space, all tabs, returns, and linefeeds
  553.    text=new StringEx(text.leftTrim()); //remove any leading spaces.
  554.    text=new StringEx(text.rightTrim()); //remove trailing spaces.
  555.    text=charReplace(text,'\n','');
  556.    text=charReplace(text,'\r','');
  557.    text=charReplace(text,'\t','');
  558.    return text;
  559.   }
  560.  
  561.  
  562.