Sandbox

From CometWiki

(Difference between revisions)
Jump to: navigation, search
m
(testing)
 
Line 1: Line 1:
-
[[Toc|                                Table of Contents]]<br/>
+
 
-
[[Abs|                              ABS function]]<br/>
+
XAP Gateway Internals
-
[[Abs|                              Absolute value]]<br/>
+
 
-
[[Access|                            ACCESS statement]]<br/>
+
There are 2 major parts to the XAP technology. The first part is what we call the CGI server and the second is what we call the XAP Gateway.
-
[[Access|                            Accessing InternetBasic directories]]<br/>
+
 
-
[[Activate|                          ACTIVATE statement]]<br/>
+
The CGI Server
-
[[Activate|                          Activating background partitions]]<br/>
+
 
-
[[Adjust|                            ADJUSTL function]]<br/>
+
The CGI server listens on the port configured for it. It expects to receive connections using the http protocol. It then performs the following steps:
-
[[Adjust|                            ADJUSTR function]]<br/>
+
 
-
[[Again|                            AGAIN statement]]<br/>
+
    It receives and assembles a whole browser request.
-
[[Allowmaximize|                    (Allow Maximize) mnemonic]]<br/>
+
    It parses the individual parts of this request, splitting out the following components:
-
[[Vartypes|                          Alphanumeric data types]]<br/>
+
 
-
[[Linelabl|                          Alphanumeric statement labels]]<br/>
+
    The CGI Environment variables.
-
[[Applications|                      Applications]]<br/>
+
    Any Cookies that the browser may have sent.
-
[[Archivemnemonics|                  Archive mnemonics]]<br/>
+
    Any query strings that the browser may have sent.
-
[[Arrays|                            Arrays (subscripted variables)]]<br/>
+
 
-
[[Asc|                              ASC function]]<br/>
+
    It then writes these items into a Keyed File* (called the XAP environment file), so that a user program can access them quickly.
-
[[Aschex|                            ASCHEX function]]<br/>
+
 
-
[[Ascii|                            ASCII chart]]<br/>
+
        CGI environment variables are written to the keyed file such that the key name is the environment variable name with dots instead of underlines separating words of the name, ie HTTP_USER_AGENT would become HTTP.USER.AGENT.
-
[[Asc|                              ASCII conversion function (ASC)]]<br/>
+
        Cookie names are preceded with a "C." so that a cookie by the name of "my cookie" would be written as "C.MY COOKIE".
-
[[Let|                              Assignment statement]]<br/>
+
        Likewise, query strings are preceded with a "Q." so that a query string by the name of "credit card number" would be written as "Q.CREDIT CARD NUMBER".
-
[[Autometafile|                    (Auto Metafile) mnemonic]]<br/>
+
 
-
[[Autotaboff|                      (Auto Tab Off) mnemonic]]<br/>
+
    If an appropriate cookie was present in the request, the CGI server establishes the context data for the connection.
-
[[Autotabon|                        (Auto Tab On) mnemonic]]<br/>
+
    It then launches the Internet Basic program designated by the SCRIPT.NAME environment variable. The program inherits a connection to the browser through the XAP gateway, any context items established in step 4 above, and the keyed file produced in step 3 above.
-
[[Autocroff|                        (AutoCROff) mnemonic]]<br/>
+
 
-
[[Autocron|                        (AutoCROn) mnemonic]]<br/>
+
Note: Any mention of "files" in this document does not necessarily mean "disk files". Files may reside in memory or disk depending on performance/sharing issues.
-
[[Autoinput|                        AUTOINPUT statement]]<br/>
+
 
-
[[Invokehelp|                        Automatic help]]<br/>
+
-
[[Activate|                          Background processing]]<br/>
+
 
-
[[Sb|                                Background screen display (SB)]]<br/>
+
The XAP Gateway
-
[[Base256|                          BASE256 function]]<br/>
+
 
-
[[Base64|                            BASE64 function]]<br/>
+
The XAP Gateway acts in response to commands included in the Internet Basic program launched by the CGI Server. The interface is very easy to learn because it contains relatively few basic commands:
-
[[Emailbcc|                        (BCC) mnemonic]]<br/>
+
 
-
[[Beginmetafile|                    (Begin Metafile) mnemonic]]<br/>
+
    Write – the program may write data to the browser through the gateway.
-
[[Beginwaitcursor|                  (BeginWaitCursor) mnemonic]]<br/>
+
 
-
[[Bf|                              (BF) mnemonic]]<br/>
+
    If no previous data has been written to the XAP Gateway, the XAP Gateway will generate a standard HTML header before sending the data to the browser. The program is free to modify this behavior through a control explained below. Otherwise, the data will be sent directly to the browser. All data is buffered for best performance.
-
[[Binary|                            BINARY function]]<br/>
+
    Control – the program may send various controls that cause the gateway to perform actions meaningful to the program. These will be described below.
-
[[Biosmouseon|                      (BIOS Mouse On) mnemonic]]<br/>
+
    Status – the program can get various pieces of information from the gateway by the use of a simple status function.
-
[[Bf|                                Blank fill (BF)]]<br/>
+
    Close – When the LUN pointing to the XAP Gateway is closed, all buffered data is sent to the browser, Context data is filed away for future connections, and the connection to the browser is gracefully closed.
-
[[Fmtmod|                            Blank if zero (BZ)]]<br/>
+
    The XAP environment file is also used as part of the interface between the program and the XAP gateway. The program can read browser request data from this file as explained above. It may also write information that will eventually be written to the browser as explained below.
-
[[Strip|                            Blank stripping]]<br/>
+
 
-
[[Bm|                                Blind mode (BM)]]<br/>
+
-
[[Blink|                            (Blink) mnemonic]]<br/>
+
 
-
[[Bm|                              (BM) mnemonic]]<br/>
+
XAP Gateway Controls
-
[[Goto|                              Branching statement, GOTO]]<br/>
+
 
-
[[Ongoto|                            Branching statement, ON/GOTO]]<br/>
+
Most of the power of the XAP Gateway is embedded in the various Controls that the program may send to it. The Control statement looks like a standard function in the language:
-
[[Break|                            BREAK statement]]<br/>
+
 
-
[[Bright|                          (Bright) mnemonic]]<br/>
+
Syntax:
-
[[Intmode#Compileroptions|          Byte-align COMMON]]<br/>
+
 
-
[[Fmtmod|                          (BZ) modifier]]<br/>
+
Result-string = CONTROL(LUN,Control.String [,EXCP=exception.routine])
-
[[Casessions|                      (CA Sessions) mnemonic]]<br/>
+
 
-
[[Capsoff|                          (CapsOff) mnemonic]]<br/>
+
The CONTROL statement sends the specified control-string to the specified logical unit number. In the case of the XAP Gateway, the Logical Unit Number or "LUN" is always 0 (zero).
-
[[Capson|                          (CapsOn) mnemonic]]<br/>
+
 
-
[[Cr|                                Carriage return (CR)]]<br/>
+
The CONTROL statement also reads the result field from the input buffer and places it in the result-string. A plus sign (+) in the first byte of the result-string indicates that the control function was performed successfully. A minus sign (-) in the first byte indicates that the control was not performed successfully. The remaining bytes of the result-string contain text describing the success or failure of the control function.
-
[[Case|                              CASE statement]]<br/>
+
 
-
[[Select|                            Case structure]]<br/>
+
The CONTROL statement performs the same function as the following statements:
-
:[[select|SELECT statement]]<br/>
+
 
-
:[[select|CASE statement (in SELECT structure)]]<br/>
+
FILE (LUN) CTL=control-string
-
:[[select|ANY MATCH statement (in SELECT structure)]]<br/>
+
 
-
:[[select|ELSE (in SELECT structure)]]<br/>
+
INPUT (LUN) result-string
-
:[[select|FROM parameter (in SELECT structure)]]<br/>
+
 
-
:[[select|IS parameter (in SELECT structure)]]<br/>
+
Here are the controls that may be sent to the XAP gateway. Where string constants are used in the examples, string expressions may also be used.
-
:[[select|MATCH parameter (in SELECT structure)]]<br/>
+
 
-
:[[select|THRU parameter (in SELECT structure)]]<br/>
+
    TYPE – sets a MIME type to the browser. As explained above if no TYPE control is sent, the type is assumed to be HTML and the appropriate header is sent to the browser..
-
[[Emailcc|                          (CC) mnemonic]]<br/>
+
 
-
[[Cf|                              (CF) mnemonic]]<br/>
+
    Result-string = CONTROL (0,"TYPE 0") notifies the XAP gateway that the program will subsequently write its own MIME type header.
-
[[Cfld|                            (CFLD) mnemonic]]<br/>
+
    result-string = CONTROL(0,"TYPE 1") tells the XAP Gateway to set the mime type to "text/html"
-
[[Ch|                              (CH) mnemonic]]<br/>
+
    result-string = CONTROL(0,"TYPE 2") tells the XAP Gateway to set the mime type to "text/plain"
-
[[Changecolor|                      (Change Color) mnemonic]]<br/>
+
    Result-string = CONTROL (0,"TYPE 3") tells the XAP Gateway to set the mime type to "text/plain" and supply automatic carriage return line feeds following every write.
-
[[Changecolors|                    (Change Colors) mnemonic]]<br/>
+
 
-
[[Doschdir|                          Change current directory]]<br/>
+
    COOKIE – sends a cookie to the browser. This control must be sent before any other data is sent to the browser because the cookie information is part of the header.
-
[[Cpl132|                            Characters per line, 132]]<br/>
+
 
-
[[Cpl64|                            Characters per line, 64]]<br/>
+
    The syntax is as follows:
-
[[Cpl80|                            Characters per line, 80]]<br/>
+
 
-
[[Checkboxoff|                      (Check Box Off) mnemonic]]<br/>
+
    A$ = CONTROL (0,'COOKIE cookie-name=cookie-value,time-period')
-
[[Checkboxon|                      (Check Box On) mnemonic]]<br/>
+
 
-
[[Chksum|                            Checksum function]]<br/>
+
    Where time-period is the specified length of time for the cookie to be stored in the browser.
-
[[Chksum|                            CHKSUM function]]<br/>
+
 
-
[[Chr|                              CHR function]]<br/>
+
    The format for time period is:
-
[[Cfld|                              Clear field (CFLD)]]<br/>
+
 
-
[[Cf|                                Clear foreground (CF)]]<br/>
+
    +nM = n minutes into the future
-
[[Cs|                                Clear screen (CS)]]<br/>
+
 
-
[[Clear|                            CLEAR statement]]<br/>
+
    +nH = n hours into the future
-
[[Clear|                            CLEARCOMMON statement]]<br/>
+
 
-
[[Clearfile|                        CLEARFILE statement]]<br/>
+
    +nD = n days into the future
-
[[Clearfmt|                          ClearFormat statement]]<br/>
+
 
-
[[Clear|                            CLEARLOCAL statement]]<br/>
+
    For example, to make the CUSTOMERNUMBER=123456789 cookie stay in the browser system for 25 days, you would use the following statement:
-
[[Dosclose|                          Close DOS file handle]]<br/>
+
 
-
[[Closeicon|      (                 Close Icon) mnemonic]]<br/>
+
    A$ = CONTROL(0,'COOKIE CUSTOMERNUMBER=123456789,+25D')
-
[[Close|                            Close InternetBasic data file]]<br/>
+
    REDIRECT – Sends the appropriate commands to the browser so that it will automatically connect to the URL contained in the REDIRECT control. This control must be sent before any other data is sent to the browser because the redirect information is part of the header.
-
[[Close|                            CLOSE statement]]<br/>
+
 
-
[[Closemouse|                        Close the mouse]]<br/>
+
    For example, if you wanted your program to redirect the browser to www.signature.net, you would use the following statement:
-
[[Screencolors|                      Colors, screen]]<br/>
+
 
-
[[Exceptionmessages|                Comet Exception Messages]]<br/>
+
    A$ = CONTROL(0,'REDIR http://www.signature.net')
-
[[Comethyperlinks|                  Comet Hyperlinks]]<br/>
+
    OPEN – performs a "test open" of the file contained in the control to validate whether it is present. This file may be a template file, html file, image file or any file. The named file is opened, and the handle is saved for further operations using that file.
-
[[Startupoptions|                    Comet Startup Options]]<br/>
+
 
-
[[Cometwindows|                      Comet Windows]]<br/>
+
    For example, if you wanted your program to send the image contained in the file "c:\images\logo.jpg" to the browser, you would use the following command:
-
[[C32Procs|                          Comet32 User Defined Procedures and Functions]]<br/>
+
 
-
[[Csv|                              Comma delimited files]]<br/>
+
    A$ = CONTROL (0,'OPEN C:\IMAGES\LOGO.JPG')
-
[[Cmdmode|                          Command Mode (compiler)]]<br/>
+
 
-
[[Comment|                          Comment Character]]<br/>
+
    After the execution of this control, the result string A$ would contain "+OK" if the file was successfully opened, or "-ERR error opening path" if the file could not be found.
-
[[Common|                            Common data fields]]<br/>
+
    SEND – Sends the file referred to in the control to the browser. The file is sent to the browser in the fastest way possible. The SEND control may specify a path pointing to the file to be sent --
-
[[Comparam|                          Common Parameters]]<br/>
+
 
-
[[Common|                            COMMON statement]]<br/>
+
    A$ = CONTROL (0,'SEND C:\IMAGES\LOGO.JPG')
-
[[Cmdmode|                          Compiler commands]]<br/>
+
 
-
[[Directiv|                          Compiler Directives]]<br/>
+
    or optionally, if no path is specified --
-
[[Compilerdirectives|                Compiler Directives]]<br/>
+
 
-
:[[DOTELSE|.ELSE directive]]<br/>
+
    A$ = CONTROL (0,'SEND')
-
:[[DOTENDIF|.ENDIF directive]]<br/>
+
 
-
:[[DOTIF|.IF directive]]<br/>
+
    the XAP gateway will send a file previously opened by the OPEN control as specified above.
-
:[[DOTIFDEF|.IFDEF directive]]<br/>
+
    PUSH – Flushes the output buffer contained in the XAP gateway to the browser for debugging purposes or to implement "server push" actions.
-
:[[DOTIFNDEF|.IFNDEF directive]]<br/>
+
    MERGE – Merges data from a template file named in the control with data contained in the CGI Environment file, Then sends the resultant merged data stream to the browser. Merge is the most powerful of all of the controls. It merges selected data from the CGI environment file with a template file (or a section of a template file) and sends the resulting web page to the browser.
-
[[Compilererrormessages|            Compiler Error Messages]]<br/>
+
 
-
[[Compiler|                          Compiler]]<br/>
+
The syntax for the MERGE control may take several forms. The general description of the merge command is:
-
[[Compile|                          Compiling programs]]<br/>
+
 
-
[[Conditionalcompilation|            Conditional compilation]]<br/>
+
A$ = CONTROL (LUN,’MERGE Path-name |"." [,SECTION Section-name])
-
[[Stmtcont|                          Continuation of a statement]]<br/>
+
 
-
[[Continue|                          CONTINUE statement]]<br/>
+
As you can see, the MERGE command takes an optional path name and an optional section name. Here is how Comet processes a MERGE command.
-
[[Wc|                                Control line]]<br/>
+
 
-
[[Control|                          CONTROL statement]]<br/>
+
        Comet first determines if there is a path name specified, or a dot, meaning use the last file either opened from a previous MERGE command or an OPEN command. If a Path name was supplied, that file is opened.
-
:[[Control_Close|                  CONTROL_CLOSE]]<br/>
+
        Comet then determines whether a SECTION name was supplied. If a Section name was specified, Comet searches the file for a string of characters such as:
-
:[[Control_Connect|                CONTROL_CONNECT]]<br/>
+
 
-
:[[Control_Crlf|                    CONTROL_CRLF]]<br/>
+
        <!—BEGIN Section-nameà
-
:[[Control_Disconnect|              CONTROL_DISCONNECT]]<br/>
+
 
-
:[[Control_Geterror|                CONTROL_GETERROR]]<br/>
+
        If found, the file pointer is set just beyond this string, causing Comet to read data from this point on. If no such string was found, Comet starts reading the e file from the first byte.
-
:[[Control_Listen|                  CONTROL_LISTEN]]<br/>
+
        If a section was specified in the control statement, Comet then searches the file for an end-of-section string. This string is of the form:
-
:[[Control_Open|                    CONTROL_OPEN]]<br/>
+
 
-
:[[Control_Quit|                    CONTROL_QUIT]]<br/>
+
        <!—END Section-nameà
-
:[[Control_Timeout|                CONTROL_TIMEOUT]]<br/>
+
 
-
:[[Control_Weol|                    CONTROL_WEOL]]<br/>
+
        If such a string is found, a pointer is set to the character just prior to the opening character of this string. This pointer marks the last character sent from the file on this Merge command. If no such string is found, the ending pointer is set to the last character of the file.
-
[[Doscopy|                          Copy a file]]<br/>
+
        Comet then searches the file starting at the current file pointer for an indicator marking data to be inserted. At the current time, this marker is a pair of stars (**).
-
[[Copyfromclipboard|                (Copy from Clipboard) mnemonic]]<br/>
+
        If such a marker is found, all data is streamed from the file to the Browser up to this marker.
-
[[Copytoclipboard|                  (Copy to Clipboard) mnemonic]]<br/>
+
        Comet then searches the file for an ending indicator. At the current time this is also a pair of stars (**). If such a marker is found, all characters between the beginning and ending markers (including the **’s) is assembled into a Key to be used in a keyed read on LUN 1. If the read is successful, the data record resulting from this keyed read is streamed to the browser.
-
[[Copyfile|                        (CopyFile) mnemonic]]<br/>
+
        If the keyed read was unsuccessful, the first * of the beginning marker is sent to the browser and the process is repeated from step d. above.
-
[[Copyright|                        Copyright notice]]<br/>
+
        Once the entire file or section has been streamed to the browser, the control command is completed.
-
[[Cpl132|                          (CPL132) mnemonic]]<br/>
+
 
-
[[Cpl64|                            (CPL64) mnemonic]]<br/>
+
It should be noted that the syntax used for the begin and end indicators denotes HTML comments. Thus the markers would not be visible in the html page if the browser displayed them.
-
[[Cpl80|                            (CPL80) mnemonic]]<br/>
+
 
-
[[Cr|                              (CR) mnemonic]]<br/>
+
It should also be noted that even though the operations above look like operations on a file, the data is really read into memory and streamed from there for performance reasons.
-
[[Doscreate|                        Create DOS file]]<br/>
+
 
-
[[Dosmkdir|                          Create DOS subdirectory]]<br/>
+
Following are two lessons from a tutorial which deal with the MERGE command:
-
[[Create|                            Create InternetBasic file]]<br/>
+
 
-
[[Create|                            CREATE statement]]<br/>
+
This lesson and the next one are the most important lessons in the eComet tutorial. In this lesson, you will learn how to merge live Comet data into stored HTML documents.
-
[[Createkey|                        Create sub key for InternetBasic file]]<br/>
+
 
-
[[Createwindow|                    (Create Window) mnemonic]]<br/>
+
Let us repeat that last part (for emphasis): you can merge live Comet data into a stored HTML document in order to make a dynamic return page.
-
[[Createkey|                        CREATEKEY statement]]<br/>
+
 
-
[[Createwindowex|                  (CreateWindowEx) mnemonic]]<br/>
+
-
[[Crsource|                          Creating IB Source Programs]]<br/>
+
 
-
[[Creatingwindows|                  Creating legacy windows]]<br/>
+
Here's how it works:
-
[[Crmode|                          (CrMode) mnemonic]]<br/>
+
 
-
[[Intmode#Compileroptions|          Cross reference file]]<br/>
+
First, create an XAP-ready HTML document. In the locations where you want to include a merge field, surround the field name with double asterisks.
-
[[Cs|                              (CS) mnemonic]]<br/>
+
 
-
[[Csv#Comma|                        CSV Files]]<br/>
+
Here's a sample HTML file. We've included one merge field named **TODAY**.
-
[[Curpos|                            CURPOS$ system variable]]<br/>
+
 
-
[[Ch|                                Cursor home (CH)]]<br/>
+
<HTML>
-
[[Curpos|                            Cursor position]]<br/>
+
 
-
[[Cr|                                Cursor return (CR)]]<br/>
+
<HEAD>
-
[[Ddstmts|                          Data Division Statements]]<br/>
+
 
-
[[Datadiv|                          Data Division]]<br/>
+
<TITLE>
-
[[Clear|                            Data Initialization statement]]<br/>
+
 
-
[[Datatype|                          Data Types]]<br/>
+
Sample merge document
-
[[Date|                              DATE system variable]]<br/>
+
 
-
[[Date|                              DATE$ system variable]]<br/>
+
</TITLE>
-
[[Date2Num|                          DATE2NUM function]]<br/>
+
 
-
[[Datetonum|                        DATETONUM function]]<br/>
+
</HEAD>
-
[[Day|                              DAY$ system variable]]<br/>
+
 
-
[[De|                              (DE) mnemonic]]<br/>
+
<BODY>
-
[[Dechex|                            DECHEX function]]<br/>
+
 
-
[[Decihex|                          DECIHEX function]]<br/>
+
This is a sample document.
-
[[Dechex|                            Decimal to hex conversion]]<br/>
+
 
-
[[If|                                Decision statements]]<br/>
+
Today's date is **TODAY**.
-
:[[if|IF statement]]<br/>
+
 
-
:[[if|ELSE (in IF structure)]]<br/>
+
</BODY>
-
:[[if|THEN parameter (in IF statement)]]<br/>
+
 
-
[[Decpass|                          DECPASS]]<br/>
+
</HTML>
-
[[Decrypt|                          DECRYPT statement]]<br/>
+
 
-
[[De|                                Default characters per line (DE)]]<br/>
+
For the sake of this example, let's suppose we saved this file on drive C: and named the file TODAY.HTM.
-
[[Delete|                            DELETE statement]]<br/>
+
 
-
[[Deletewindow|                    (Delete Window) mnemonic]]<br/>
+
Next, write an Internet Basic program that does two things:
-
[[Deletewindowex|                  (DeleteWindowEx) mnemonic]]<br/>
+
 
-
[[Deletingwindows|                  Deleting legacy windows]]<br/>
+
1.Writes the merge field(s) to the CGI Environment File, using the double-asterisk field name as the key
-
[[Delete|                            Deleting records]]<br/>
+
 
-
[[Detectingclicks|                  Detecting mouse clicks]]<br/>
+
2.Merges the HTML document with the CGI Environment File via the MERGE command
-
[[Dstat|                            Device status]]<br/>
+
 
-
[[Dir|                              DIR= parameter]]<br/>
+
Here's some sample code to show you how this works:
-
[[Compilerdirectives|                Directives (compiler)]]<br/>
+
 
-
[[Access|                            Directory access]]<br/>
+
LENGTH 10 & LOCAL TODAY$
-
[[Directoryaliases|                  Directory Aliases Overview]]<br/>
+
 
-
[[Do|                                DO loop]]<br/>
+
CGIDATA: FORMAT TODAY$
-
:[[do|DO (in DO/LOOP structure)]]<br/> 
+
 
-
:[[do|UNTIL parameter (in DO/LOOP structure)]]<br/> 
+
TODAY$ = '06/08/2000'
-
:[[do|WHILE parameter (in DO/LOOP structure)]]<br/> 
+
 
-
:[[do|LOOP (in DO/LOOP structure)]]<br/>
+
WRITE (1,CGIDATA) KEY='**TODAY**' ! Write merge field
-
[[Document|                        (Document) mnemonic]]<br/>
+
 
-
[[Emaildomain|                      (Domain) mnemonic]]<br/>
+
A$ = CONTROL(0,'MERGE C:\TODAY.HTM') ! Merge the HTML file
-
[[Doscallsbackground|                DOS Calls Background Discussion]]<br/>
+
 
-
[[Dosgetdate|                        DOS date]]<br/>
+
The WRITE statement writes a record to the CGI Environment file (remember, this file is automatically opened on Logical Unit Number 1 when the XAP program is started). The key is the same as the merge field name in the HTML document (i.e.,**TODAY**).
-
[[Dosdirectcalls|                    DOS Direct Calls]] <br/>
+
 
-
[[Dosfcalls|                        DOS Function Calls]]<br/>
+
The MERGE command merges the HTML document (C:\TODAY.HTM) with any merge field(s) contained in the CGI Environment File. In this example, there's only one merge field.
-
[[Dosfc|                            DOSFC function]]<br/>
+
 
-
[[Dosms|                            DOSMS function]]<br/>
+
The result is a web page that contains "06/08/2000" in the exact location where "**TODAY**" was contained in the stored document.
-
[[Dosrw|                            DOSRW function]]<br/>
+
 
-
[[Drawbitmap|                      (Draw Bit Map) mnemonic]]<br/>
+
Here are some important notes:
-
[[Drawbox|                         (Draw box) mnemonic]]<br/>
+
 
-
[[Drawimage|                        (Draw Image) mnemonic]]<br/>
+
The MERGE command is very similar to the SEND command (i.e., it sends a stored document from the eComet system to the browser.
-
[[Drawtext|                        (Draw Text) mnemonic]]<br/>
+
 
-
[[Dstat|                            DSTAT function]]<br/>
+
The merge field(s) can appear anywhere in the stored document. This means that you can merge Comet data into places where you want data to appear, and you can also merge HTML commands into a stored document (to change the appearance of a web page for a particular user, for example).
-
:[[dstat#console|DSTAT of the console]]<br/> 
+
 
-
:[[dstat#remoteterminals|DSTAT of remote terminals]]<br/> 
+
Here's another example. Remember the program (from Lesson 2) that displayed several Comet system variables? Well, we've rewritten that example using the MERGE command.
-
:[[dstat#localprinter|DSTAT of a local printer]]<br/> 
+
 
-
:[[dstat#remoteprinter|DSTAT of a remote printer]]<br/> 
+
First, we created an HTML document and included several merge fields. The "raw" document is named systvar.htm. Take a look at the HTML source code and notice the merge fields (**PARTITION** and the others).
-
:[[dstat#spooler|DSTAT of a spooler]]<br/> 
+
 
-
:[[dstat#x00|DSTAT of the system device (X00)]]<br/> 
+
Next, we created an Internet Basic program that writes the desired merge records to the CGI Environment File. Look at the following source code and notice the WRITE statements.
-
:[[dstat#gateway|DSTAT of a gateway]]<br/> 
+
 
-
:[[dstat#directory|DSTAT of a directory]]<br/> 
+
!---------------------------------------------------------------------
-
[[dstat#clock|DSTAT of the clock]]<br/>
+
 
-
[[Easyscan|                        (Easy Scan) mnemonic]]<br/>
+
!
-
[[Editmask|                          Edit masks]]<br/>
+
 
-
:[[EDITMASKELEMENTS|Edit mask elements]]<br/>
+
! *** Main program
-
:[[editmaskexamples|Edit mask examples]]<br/>
+
 
-
:[[EDITMSK2|Additional Edit Mask Examples]]<br/>
+
!
-
[[Creating|                          Editing source programs]]<br/>
+
 
-
[[Linelabl|                          Editor line numbers]]<br/>
+
A$ = DSTAT('CL1') ! Refresh TIME$
-
[[Http://Signature.Net:8080/Xap/Tutorial|eInternetBasic Tutorial]]<br/>
+
 
-
[[Ellipse|                          (Ellipse) mnemonic]]<br/>
+
!
-
[[Emailmnemonics|                    Email printer mnemonics]]<br/>
+
 
-
[[Emaildoc|                        (EmailDocument) mnemonic]]<br/>
+
OPEN (10) '#CGICTRL' ! Open CGI control file
-
[[En|                              (EN) mnemonic]]<br/>
+
 
-
[[Encrypt|                          ENCRYPT statement]]<br/>
+
READ (10,HTMLPATH) KEY='**HTMLPATH**' ! Get HTML path
-
[[Endmetafile|                      (End Metafile) mnemonic]]<br/>
+
 
-
[[End|                              END statement]]<br/>
+
HTMLPATH$ = STRIP(HTMLPATH$) ! Strip blanks
-
[[Endif|                            ENDIF statement]]<br/>
+
 
-
[[Endselect|                        ENDSELECT statement]]<br/>
+
CLOSE (10)
-
[[Enduse|                            ENDUSE directive]]<br/>
+
 
-
[[Endwaitcursor|                    (EndWaitCursor) mnemonic]]<br/>
+
!
-
[[Enhancedcharacterset|              Enhanced Character Set]]<br/>
+
 
-
:[[enhancedcharactersoff|(Enhanced Characters Off) mnemonic]]<br/> 
+
! *** Write merge fields to CGI file
-
:[[enhancedcharacterson|(Enhanced Characters On) mnemonic]]<br/>
+
 
-
[[Enhancedmouseon|                  (Enhanced Mouse On) mnemonic]]<br/>
+
!
-
[[En|                                Enter normal mode (EN)]]<br/>
+
 
-
[[Enter|                            ENTER statement]]<br/>
+
OUTPUT$ = PARTITION$ ! Partition #
-
[[Et|                                Enter typewriter mode (ET)]]<br/>
+
 
-
[[Enterlevel|                        ENTERLEVEL system variable]]<br/>
+
WRITE (1,OUTPUT) KEY='**PARTITION**' ! Write record
-
[[Doserase|                          Erase DOS file]]<br/>
+
 
-
[[Erase|                            Erase InternetBasic file]]<br/>
+
!
-
[[Erase|                            ERASE statement]]<br/>
+
 
-
[[Erasefile|                        (EraseFile) mnemonic]]<br/>
+
OUTPUT$ = TIME$ ! System time
-
[[Compilererrormessages|            Error messages (IB compiler)]]<br/>
+
 
-
[[Error|                            ERROR statement]]<br/>
+
WRITE (1,OUTPUT) KEY='**TIME**' ! Write record
-
[[Errorsub|                          ERRORSUB statement]]<br/>
+
 
-
[[Errorto|                          ERRORTO statement]]<br/>
+
!
-
[[Escapesub|                        ESCAPESUB statement]]<br/>
+
 
-
[[Escapeto|                          ESCAPETO statement]]<br/>
+
OUTPUT$ = DATE$ ! System date
-
[[Et|                              (ET) mnemonic]]<br/>
+
 
-
[[Eventsub|                          EVENTSUB statement]]<br/>
+
WRITE (1,OUTPUT) KEY='**DATE**' ! Write record
-
[[Eventwait|                        EVENTWAIT statement]]<br/>
+
 
-
[[Excphndl|                          Exception Handling]]<br/>
+
!
-
[[Exceptionmessages|                Exception messages]]<br/>
+
 
-
[[Excpparm|                          EXCP parameter]]<br/>
+
OUTPUT$ = LONGYEAR$ ! 4-digit year
-
[[Excp|                              EXCP system variable]]<br/>
+
 
-
[[Excpparm|                          EXCP=]]<br/>
+
WRITE (1,OUTPUT) KEY='**LONGYEAR**' ! Write record
-
[[Excpsub|                          EXCPSUB=]]<br/>
+
 
-
[[Executemetafile|                  (Execute Metafile) mnemonic]]<br/>
+
!
-
[[Exepass|                          EXEPASS]]<br/>
+
 
-
[[Exit|                              EXIT statement]]<br/>
+
OUTPUT$ = VERSION$ ! Version #
-
[[Exitall|                          EXITALL statement]]<br/>
+
 
-
[[Exitto|                            EXITTO statement]]<br/>
+
WRITE (1,OUTPUT) KEY='**VERSION**' ! Write record
-
[[Extract|                          EXTRACT statement]]<br/>
+
 
-
[[False|                            FALSE]]<br/>
+
!
-
[[Doscopy|                          Fast copy]]<br/>
+
 
-
[[Fax|                              Fax gateway]]<br/>
+
! *** Merge the CGI file with the HTML file, and send the results
-
[[Ff|                              (FF) mnemonic]]<br/>
+
 
-
[[Filepos|                          File BOF parameter]]<br/>
+
!
-
[[Filebuf|                          File BUF parameter]]<br/>
+
 
-
[[Filebuf|                          File Buffer size]]<br/>
+
MERGESTRING$ = 'MERGE '+HTMLPATH$ + 'systvar.htm' ! Build MERGE string
-
[[Filectl|                          File CTL parameter]]<br/>
+
 
-
[[Filedlm|                          File Delimiter string]]<br/>
+
A$ = CONTROL(0,MERGESTRING$) ! Merge
-
[[Filedlm|                          File DLM parameter]]<br/>
+
 
-
[[Filepos|                          File EOF parameter]]<br/>
+
!
-
[[Filectl|                          File FLUSH]]<br/>
+
 
-
[[Fileforward|                      File FORWARD (file direction)]]<br/>
+
KILL PARTITION$
-
[[Dosgethandles|                    File handles function]]<br/>
+
 
-
[[Fileops|                          File I/O Operations]]<br/>
+
Note
-
[[Lock|                              File locking]]<br/>
+
 
-
[[File|                              File statement]]<br/>
+
The MERGE command may also be executed via the FILE statement, as shown here:
-
:[[filebuf|FILE BUF]]<br/> 
+
 
-
:[[filectl|FILE CTL]]<br/> 
+
FILE (0) CTL='MERGE ______________'
-
:[[filedlm|FILE DLM]]<br/> 
+
 
-
:[[fileforward|FILE FORWARD]]<br/>
+
HTML file name
-
:[[filepos|FILE POS]]<br/> 
+
 
-
:[[filereverse|File REVERSE (file direction)]]<br/>
+
-
:[[csv|FILE CSV]]<br/>
+
 
-
:[[Xml|FILE XML]]<br/>
+
In Lesson 3, we showed you how to send multiple stored documents to the web browser with the SEND command. The MERGE command can be used to do the same thing.
-
[[Fstat|                            File status]]<br/>
+
 
-
[[Filesyst|                          File system overview]]<br/>
+
For example, here's a program segment that sends 3 stored documents via the MERGE command:
-
[[Filectl|                          File Tab-delimted fields in text files]]<br/>
+
 
-
[[Filesyst|                          File types]]<br/>
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3x.htm')
-
[[Filestatus|                      (FileStatus) mnemonic]]<br/>
+
 
-
[[Dosfindreverse|                    Find a string -- reverse]]<br/>
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3y.htm')
-
[[Dosfind|                          Find a string]]<br/>
+
 
-
[[Findfirstfile|                    (FindFirstFile) mnemonic]]<br/>
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3z.htm')
-
[[Findnextfile|                    (FindNextFile) mnemonic]]<br/>
+
 
-
[[First|                            FIRST function]]<br/>
+
Please note these differences between SEND and MERGE:
-
[[Flush|                            (Flush) mnemonic]]<br/>
+
 
-
[[For|                              FOR statement]]<br/>
+
The MERGE command invokes the merge feature, while the SEND command does not
-
:[[for|TO parameter (in FOR statement)]]<br/>
+
 
-
:[[next|NEXT statement]]<br/>
+
There's another very important difference between SEND and MERGE. The MERGE command can send sections of an HTML document. The sections are user-defined portions of the HTML file.
-
[[Forceclose|                      (Force Close) mnemonic]]<br/>
+
 
-
[[Forcelogout|                      (Force Logout) mnemonic]]<br/>
+
These sections are defined via the HTML comment tag and some XAP-specific keywords within each comment. Here's an example:
-
[[Ft|                                Force transmit (FT)]]<br/>
+
 
-
[[Sf|                                Foreground screen display]]<br/>
+
<!--BEGIN ABC123-->
-
[[Ff|                                Form feed (FF)]]<br/>
+
 
-
[[Fmtitem|                          Format item]]<br/>
+
This is a section of HTML code. This
-
[[Fmtobj|                            Format objects]]<br/>
+
 
-
[[Format|                            FORMAT statement]]<br/>
+
section includes text as well as HTML
-
[[Fpt|                              FPT function]]<br/>
+
 
-
[[Fpt|                              Fractional portion]]<br/>
+
<font color="ff0000">commands</font>.
-
[[Emailfrom|                        (From) mnemonic]]<br/>
+
 
-
[[Fstat|                            FSTAT function]]<br/>
+
<p>
-
[[Ft|                              (FT) mnemonic]]<br/>
+
 
-
[[Fullscancodespassed|              (Full Scan Codes Passed) mnemonic]]<br/>
+
This whole section is defined by the
-
[[Getconnectioninfo|                (Get Connection Info) mnemonic]]<br/>
+
 
-
[[Dosgetdate|                        Get DOS date]]<br/>
+
BEGIN and END statements, which are
-
[[Dosgettime|                        Get DOS time]]<br/>
+
 
-
[[Getextractinfo|                  (Get Extract Info) mnemonic]]<br/>
+
contained within HTML comments.
-
[[Dosgethandles|                    Get Handles function]]<br/>
+
 
-
[[Getrop2|                          (Get ROP2) mnemonic]]<br/>
+
<!--END ABC123-->
-
[[Getservertime|                    (Get Server Time) mnemonic]]<br/>
+
 
-
[[Getsessionid|                    (Get Session ID) mnemonic]]<br/>
+
The browser ignores the BEGIN and END statements, since they're contained within HTML comments. However, the MERGE command uses the BEGIN and END commands to defined a section of the file. This section is called ABC123.
-
[[Getbkcolor|                      (GetBkColor) mnemonic]]<br/>
+
 
-
[[Getbkmode|                        (GetBkMode) mnemonic]]<br/>
+
Assume that you saved the above HTML file as:
-
[[Getdiralias|                      (GetDirAlias) mnemonic]]<br/>
+
 
-
[[Getfontinfo|                      (GetFontInfo) mnemonic]]<br/>
+
c:\ecomet\html\test.htm
-
[[Getfmt|                            GetFormat statement]]<br/>
+
 
-
[[Getfuncresult|                    (GetFuncResult) mnemonic]]<br/>
+
Here's how you would send this section of the HTML file via the MERGE command:
-
[[Getglobal|                        GetGlobal statement]]<br/>
+
 
-
[[Getpageinfo|                      (GetPageInfo) mnemonic]]<br/>
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\test.htm SECTION ABC123')
-
[[Getsessionprinter|                (GetSessionPrinter) mnemonic]]<br/>
+
 
-
[[Getsystemtime|                    (GetSystemTime) mnemonic]]<br/>
+
Some important notes:
-
[[Gettextalign|                    (GetTextAlign) mnemonic]]<br/>
+
 
-
[[Gettextcolor|                    (GetTextColor) mnemonic]]<br/>
+
    There is no limit to the number of sections you may define
-
[[Gettextextent|                    (GetTextExtent) mnemonic]]<br/>
+
 
-
[[Gosub|                            GOSUB statement]]<br/>
+
    The first section in an HTML document does not require a <!--BEGIN--> statement
-
[[Goto|                              GOTO statement]]<br/>
+
 
-
[[Gdimnemonics|                      Graphics Device Interface (GDI) mnemonics]]<br/>
+
    The final section does not require an <!--END--> statement.
-
[[Dosgethandles|                    Handles (file)]]<br/>
+
 
-
[[Helpmessages|                      Help messages]]<br/>
+
    No blank spaces are allowed at the beginning of these commands (i.e., inside of the "<!--BEGIN" string and the "<!--END" string)
-
[[Novahelpsystem|                    Help system]]<br/>
+
    Each section must have an alphanumeric section label (currently a maximum of 28 characters per label)
-
[[Helpkey|                          HELPKEY$ system variable]]<br/>
+
    When using sections in an HTML document, make sure all of your HTML code and text is between a <!--BEGIN--> statement and an <!--END--> statement. Content outside of those boundaries will not be sent to the browser.
-
[[Hexcons|                          HEX constants]]<br/>
+
 
-
[[Hexasc|                            HEXASC function]]<br/>
+
The next example is based on the sample program you saw in Lesson 4. In this case, we will be merging data from a Comet data file, the DLRS file, into a stored HTML document.
-
[[Hexdec|                            HEXDEC function]]<br/>
+
 
-
[[Hidecursor|                      (Hide Cursor) mnemonic]]<br/>
+
The HTML document will be divided into 3 sections, named TOP, MIDDLE, and BOTTOM.
-
[[Hidemousecursor|                  (Hide Mouse Cursor) mnemonic]]<br/>
+
 
-
[[Hyperlink|                        (HyperLink) mnemonic]]<br/>
+
The TOP section will contain the initial HTML commands and text for the top portion of the web page. Since this is the first section, we don't need a <!--BEGIN--> statement.
-
[[Hyperlinkcolor|                  (HyperLinkColor) mnemonic]]<br/>
+
 
-
[[Formatdiv|                        I/O Format Division]]<br/>
+
<HTML>
-
[[Compilererrormessages|            IB compiler error messages]]<br/>
+
 
-
[[Ignorewindows|                    (Ignore Windows) mnemonic]]<br/>
+
<HEAD>
-
[[Ihexdec|                          IHEXDEC function]]<br/>
+
 
-
[[Include|                          INCLUDE directive]]<br/>
+
<TITLE>
-
[[Includefile|                      Include files]]<br/>
+
 
-
[[Indent|                            Indentation]]<br/>
+
Comet Dealers
-
[[Sequent|                          Indexed Sequential files]]<br/>
+
 
-
[[Initinputdata|                    (Init Input Data) mnemonic]]<br/>
+
</TITLE>
-
[[Iterm|                            Initiating terminal]]<br/>
+
 
-
[[Input2|                            INPUT statement (without Transmit Marks)]]<br/>
+
</HEAD>
-
[[Input|                            INPUT statement]]<br/>
+
 
-
[[Inputprintfile|                    INPUTFILE statement]]<br/>
+
<BODY BGCOLOR="FFFFFF">
-
[[Inquire|                          INQUIRE statement]]<br/>
+
 
-
[[Insertoff|                        (Insert Off) mnemonic]]<br/>
+
<CENTER>
-
[[Inserton|                        (Insert On) mnemonic]]<br/>
+
 
-
[[Insert|                            INSERT statement]]<br/>
+
<H1>
-
[[Int|                              INT function]]<br/>
+
 
-
[[Int|                              Integer portion]]<br/>
+
Comet Dealers
-
[[Intel|                            INTEL function]]<br/>
+
 
-
[[Inteld|                            INTELD function]]<br/>
+
</H1>
-
[[Interrupt|                        Inter-partition communications]]<br/>
+
 
-
[[Intmode|                          Interactive Mode (compiler)]]<br/>
+
</CENTER>
-
[[Ibapps|                            Internet Basic Applications]]<br/>
+
 
-
[[Statements|                        Internet Basic statements]]<br/>
+
<HR>
-
[[Refguide|                          Internet Basic: Reference Guide]]<br/>
+
 
-
[[Intro|                            Internet Basic]]<br/>
+
Here is a list of Comet dealers.
-
[[Num2Date|                          Internet date format]]<br/>
+
 
-
[[Emailengine|                      InternetBasic Electronic Mail]]<br/>
+
This data is contained in a
-
[[Internetbasicexceptionmessages|    InternetBasic exception messages]]<br/>
+
 
-
[[Filesyst|                          InternetBasic file system]]<br/>
+
Comet keyed file named <B>DLRS</B>.
-
[[Novahelpsystem|                    InternetBasic help system (NOVA)]]<br/>
+
 
-
[[Internetbasicstartupoptions|      InternetBasic Startup Options]]<br/>
+
The DEMO11B program reads records
-
[[Internetbasicwindows|              InternetBasic windows]]<br/>
+
 
-
[[Interrupt|                        INTERRUPT statement]]<br/>
+
from that file and displays the
-
[[Interrupt|                        Interrupting another partition]]<br/>
+
 
-
[[Intro|                            Introduction to Internet Basic]]<br/>
+
complete list of names.
-
[[Invokehelp|                      (Invoke HELP) mnemonic]]<br/>
+
 
-
[[Iterm|                            ITERM$ system variable]]<br/>
+
<P>
-
[[Key|                              KEY function]]<br/>
+
 
-
[[Keyed#Keyonly|                    Key-only files]]<br/>
+
<!--END TOP-->
-
[[Keyparam|                          KEY= parameter]]<br/>
+
 
-
[[Keyed|                            Keyed files]]<br/>
+
The MIDDLE section will be very short. In this section, we will include a merge field named **DEALER**, followed by a line break tag (<BR>):
-
[[Keystat|                          KeyStat Function]]<br/>
+
 
-
[[Killsession|                      (Kill Session) mnemonic]]<br/>
+
<!--BEGIN MIDDLE-->
-
[[Kill|                              KILL statement]]<br/>
+
 
-
[[Kill|                              Killing another job]]<br/>
+
**DEALER**
-
[[Language|                          Language Structure]]<br/>
+
 
-
[[Last|                              LAST function]]<br/>
+
<BR>
-
[[Last|                              Last key]]<br/>
+
 
-
[[Launch|                          (Launch) mnemonic]]<br/>
+
<!--END MIDDLE-->
-
[[Launching|                        Launching a program or document]]<br/>
+
 
-
[[Lcase|                            LCASE function]]<br/>
+
By itself, the MIDDLE section does not look very impressive. Just wait until you see the way we use Internet Basic to merge data into this section!
-
[[Ld|                              (LD) mnemonic]]<br/>
+
 
-
[[Fmtmod|                            Leading minus sign]]<br/>
+
The BOTTOM section will contain the final HTML commands for our sample web page:
-
[[Adjust|                            Left justify function]]<br/>
+
 
-
[[Legacycompileroptions|            Legacy Compiler options]]<br/>
+
<!--BEGIN BOTTOM-->
-
[[Len|                              LEN function]]<br/>
+
 
-
[[Fmtlen|                            Length override]]<br/>
+
</BODY>
-
[[Length|                            LENGTH statement]]<br/>
+
 
-
[[Let|                              LET statement]]<br/>
+
</HTML>
-
[[Lf|                              (LF) mnemonic]]<br/>
+
 
-
[[Li|                              (LI) mnemonic]]<br/>
+
<!--END BOTTOM-->
-
[[Ld|                                Line delete (LD)]]<br/>
+
 
-
[[Lf|                                Line feed (LF)]]<br/>
+
We'll save the above file and name it:
-
[[Ls|                                Line feed suppress (LS)]]<br/>
+
 
-
[[Li|                                Line insert (LI)]]<br/>
+
c:\ecomet\html\dealers.htm
-
[[Linelabl|                          Line Numbers vs. Labels]]<br/>
+
 
-
[[Lineto|                          (Line To) mnemonic]]<br/>
+
Now all we have to do is write an Internet Basic program that sends the 3 sections (and merged data) to the web browser. The first MERGE command will send SECTION TOP:
-
[[Linespacing|                      (LineSpacing) mnemonic]]<br/>
+
 
-
[[Compilercommands|                  LIST command]]<br/>
+
A$ = CONTROL(0,'MERGE c:\ecomet\html\dealers.htm SECTION TOP')
-
[[Fmtmod|                          (LM) modifier]]<br/>
+
 
-
[[Loadcontrol|                      (LoadControl) mnemonic]]<br/>
+
The next part of the Internet Basic program will READ data from the DLRS file, WRITE a key to the CGI Environment File, and MERGE SECTION MIDDLE. These steps will be repeated for all of the records in the DLRS file:
-
[[Local|                            LOCAL statement]]<br/>
+
 
-
[[Extract|                          Lock data record]]<br/>
+
OPEN (10) 'DLRS'
-
[[Lock|                              Lock InternetBasic data file]]<br/>
+
 
-
[[Lock|                              LOCK statement]]<br/>
+
ReadMore:
-
[[Lockdabs|                          LockDabs statement]]<br/>
+
 
-
[[Log|                              LOG statement]]<br/>
+
READ (10,DEALERINFO) EXCP=AllDone
-
[[Emaillog|                        (Log) mnemonic]]<br/>
+
 
-
[[Lun|                              Logical unit number (lun)]]<br/>
+
WRITE (1,DEALERINFO) KEY='**DEALER**'
-
[[Longyear|                          LONGYEAR system variable]]<br/>
+
 
-
[[Longyear|                          LONGYEAR$ system variable]]<br/>
+
A$ = CONTROL(0,'MERGE . SECTION MIDDLE')
-
[[Customlookup|                      Lookup programs]]<br/>
+
 
-
[[Loop|                              LOOP statement]]<br/>
+
GOTO ReadMore
-
[[Lcase|                            Lower case conversion]]<br/>
+
 
-
[[Ls|                              (LS) mnemonic]]<br/>
+
Notice that the key value (**DEALER**) matches the merge field in the HTML file.
-
[[Doslseek|                          LSEEK function]]<br/>
+
 
-
[[Mid|                              Machine ID number]]<br/>
+
Also notice that the MERGE command contains a different format than before. If you are merging more than one section of an HTML file, you only have to specify the file name once (on the first MERGE command). After that, you can use the period (.) to represent the HTML file name.
-
[[Frames|                            Main]]<br/>
+
 
-
[[Mapmode|                          (Map Mode) mnemonic]]<br/>
+
The period is both a coding shortcut and a way to get faster performance from the MERGE command. Once an HTML file has been opened and read into memory, there's no need to re-open and re-read it. Thus, the period refers to a document that is already in memory.
-
[[Mc|                              (MC) mnemonic]]<br/>
+
 
-
[[Dosmessageall|                    Message sending to all terminals]]<br/>
+
The final section the program closes the data file and sends the BOTTOM section of the HTML file:
-
[[Dosmessage|                        Message sending to another terminal]]<br/>
+
 
-
[[Message|                          MESSAGE$ system variable]]<br/>
+
AllDone:
-
[[Messagesub|                        MESSAGESUB statement]]<br/>
+
 
-
[[Metafiles|                        Metafiles overview]]<br/>
+
CLOSE (10)
-
[[Mid|                              MID function]]<br/>
+
 
-
[[Mousedrivermnemonics|              Mnemonics, mouse driver]]<br/> 
+
A$ = CONTROL(0,'MERGE . SECTION BOTTOM')
-
[[Spoolmessage|                      Mnemonics, spooler]] <br/> 
+
 
-
[[Systemdrivermnemonics|            Mnemonics, System driver]]<br/>
+
KILL PARTITION$
-
[[Videomnemonics|                    Mnemonics, Video]]  <br/>
+
 
-
[[Windowsprintermnemonics|          Mnemonics, Windows printer]] <br/> 
+
Here's something to Think About
-
[[Mousedriver|                      Mouse driver]]<br/>
+
 
-
:[[mousedemo| Mouse demo program]]<br/>
+
As we mentioned above, merge fields can appear anywhere in an HTML file, including HTML commands and parameters. For example, you could include a merge field where you would normally include a hard-coded parameter, as in the BACKGROUND portion of the BODY tag:
-
:[[mousedrivermnemonics|Mouse driver mnemonics]] <br/>
+
 
-
:[[easyscan|Mouse on via (Easy Scan)]]<br/>
+
<BODY BACKGROUND="**PICTURE**">
-
:[[mousesampleprograms|Mouse sample programs]]<br/>
+
 
-
[[Menhancedcharacterset|            Mouse Enhanced Character Set]]<br/>
+
Then, from within an Internet Basic program, you could define a specific background graphic simply by writing the **PICTURE** key to the CGI Environment File and merging it with your HTML file.
-
[[Mouseoff|                        (Mouse Off) mnemonic]]<br/>
+
 
-
[[Mpseudocode|                      Mouse Pseudocode]]<br/>
+
PICTURE: FORMAT PICTURE$
-
[[Dosmove|                          Move a file]]<br/>
+
 
-
[[Doslseek|                          Move DOS file read/write pointer]]<br/>
+
.
-
[[Move|                              MOVE statement]]<br/>
+
 
-
[[Move|                              Move string field]]<br/>
+
PICTURE$ = "SAMPLE.GIF"
-
[[Moveto|                          (Move To) mnemonic]]<br/>
+
 
-
[[Msgboxfunc|                        MSGBOX function]]<br/>
+
WRITE (1,PICTURE) KEY="**PICTURE**"
-
[[Msgbox|                            MSGBOX statement]]<br/>
+
 
-
[[Ddlmultipleparameters|            Multiple parameters]]<br/>
+
A$ = CONTROL(0,'MERGE HTML-document SECTION section-name')
-
[[Multstmt|                          Multiple Statements on a Line]]<br/>
+
 
-
[[Left|                              Navigation]]<br/>
+
You could use this technique to good effect, for example, by displaying a unique background graphic for each customer who uses your web site. You could determine who's who by reading a persistent cookie (assuming you had already sent one to the browser), getting unique data from that cookie (a customer number, let's say), and using that data to read a GIF or JPG file name from a keyed file. Then you could write that file name to the CGI Environment File and merge it into an HTML file, as shown in the code segment above. This would result in a very personalized web site for each of your customers.
-
[[Noexcp|                            NOEXCP]]<br/>
+
 
-
[[Normalinput|                      (Normal Input) mnemonic]]<br/>
+
-
[[En|                                Normal mode (EN)]]<br/>
+
 
-
[[Not|                              NOT function]]<br/>
+
*Keyed Files
-
[[Notation|                          Notation Conventions]]<br/>
+
 
-
[[Functionkeys|                      NOVA Function Keys]]<br/>
+
Keyed files provide direct access to the data records.
-
[[Controlfile|                      NOVA help system control file]]<br/>
+
 
-
[[Novahelpsystem|                    NOVA help system]]<br/>
+
Comet stores data for keyed files in two DOS disk files. One DOS file stores the data records in their entered order, and a "key tree" file stores the record keys in ascending ASCII order.
-
[[Linkingmethods|                    NOVA Linking Methods]]<br/>
+
 
-
[[Num|                              NUM function]]<br/>
+
An individual record may be retrieved using this identifier using the KEY= parameter of the READ (or associated input) statement.
-
[[Num2Date|                          NUM2DATE function]]<br/>
+
 
-
[[Numericoperators|                  Numeric Operators]]<br/>
+
A keyed file may also be read in key-sequential order; records are retrieved in ascending sorted key order.
-
[[Numtodate|                        NUMTODATE function]]<br/>
+
 
-
[[Compilercommands|                  OBJECT command]]<br/>
+
The index for a keyed file is a string field from 1 to 64 characters long. When the file is created, the key length is specified. So is the record length; this value ranges from 1 to 1,024 bytes, and is fixed for each record in the file. Because of the ease of use and advantages of direct access, keyed files are the most common types of data files used in Internet Basic applications.
-
[[Odbc|                              ODBC gateway]]<br/>
+
 
-
[[Ongoto|                            ON/GOTO statement]]<br/>
+
When an Internet Basic program opens a keyed file, the Comet operating system assigns a unique file pointer to the file. Each user opening the file is assigned a unique pointer, allowing multiple users to access data from the same file at the same time. To avoid data integrity problems when more than one user is accessing a file, Internet Basic provides a record locking mechanism. The EXTRACT statement is used to read and lock individual data records.
-
[[Dosopen|                          Open DOS file]]<br/>
+
 
-
[[Open|                              Open InternetBasic data file]]<br/>
+
As a user accesses records in a keyed file, the file pointer keeps track of the current location. When the file is opened, the pointer is located at the record associated with the first key. If the records are retrieved without an index, the pointer moves along in ascending ASCII order of the key values (i.e., in key-sequential order).
-
[[Open|                              OPEN statement]]<br/>
+
 
-
[[Mouseon|                          Open the mouse]]<br/>
+
When a record is accessed directly using an index, the pointer is moved to the associated position. If no record is found matching the specified index, an exception occurs, but the pointer is located at the index following the requested index value. From this point, the program could retrieve records in sequence (without an index), or retrieve another record from the file using another index value.
-
[[Operation|                        Operators]]<br/>
+
 
-
:[[operation#logical|AND operator]]<br/>
+
Keyed files may also be accessed with a numeric index. In this case, the index value is used to specify the record number in the file in record number sequence (rather than in key sequence).
-
:[[operation#logical|Logical Operations]]<br/>
+
 
-
:[[operation#logical|OR operator]]<br/>
+
Application notes:
-
:[[operation#modulo|MOD operator]]<br/>
+
 
-
:[[operation#modulo|Modulo operation]]<br/>
+
    Since Key trees are built using "Balanced B Tree" structures, access to specific records is very fast. Depending on key length, access to a single record in a file of several million records may only take 3 or 4 reads from the underlying file system.
-
:[[operation#numeric|Numeric Operations]]<br/>
+
    A keyed file provides the most convenient way to randomly access a file. Therefore, most Internet Basic programs use keyed files to store data records.
-
:[[operation#relational|Contains Operator]]<br/>
+
    When a record is deleted from a keyed file, the vacated space is automatically reused by the file to store subsequent records. This advantage is another reason why keyed files are predominant in Internet Basic applications.
-
:[[operation#relational|Relational Operations]]<br/>
+
-
:[[operation#relational|SoundsLike Operator]]<br/>
+
-
:[[operation#string|String Operations]]<br/>
+
-
:[[operation#subtraction|Subtraction]]<br/>
+
-
[[Ddlotherexamples|                  Other examples]]<br/>
+
-
[[Filesyst|                          Overview of the InternetBasic File System]]<br/>
+
-
[[Pad|                              PAD function]]<br/>
+
-
[[Partialscancodesoff|              (Partial Scan Codes Off) mnemonic]]<br/>
+
-
[[Partialscancodeson|              (Partial Scan Codes On) mnemonic]]<br/>
+
-
[[Scancodes|                        Partial Scan Codes]]<br/>
+
-
[[Pcomm|                            Partition COMMON data]]<br/>
+
-
[[Activate|                          Partition control]]<br/>
+
-
[[Priority|                          Partition priority]]<br/>
+
-
[[Pstat|                            Partition status]]<br/>
+
-
[[Partitio|                          PARTITION$ system variable]]<br/>
+
-
[[Password|                          PASSWORD function]]<br/>
+
-
[[Password|                          Password security system]]<br/>
+
-
[[Path|                              PATH function]]<br/>
+
-
[[Pause|                            PAUSE statement]]<br/>
+
-
[[Pcomm|                            PCOMM function]]<br/>
+
-
[[Playsound|                        (Play Sound) mnemonic]]<br/>
+
-
[[Pollingmouse|                      Polling the mouse]]<br/>
+
-
[[Popfont|                          (Pop Font) mnemonic]]<br/>
+
-
[[Pop|                              POP statement]]<br/>
+
-
[[Popall|                            POPALL statement]]<br/>
+
-
[[Ports|                            Ports used by Signature Products]]<br/>
+
-
[[Pos|                              POS function]]<br/>
+
-
[[Position|                          Position file pointer]]<br/>
+
-
[[Position|                          POSITION statement]]<br/>
+
-
[[Fmtpos|                            Position]]<br/>
+
-
[[Prev|                              PREV function]]<br/>
+
-
[[Prev|                              Previous key]]<br/>
+
-
[[Print|                            PRINT statement]]<br/>
+
-
[[Fmtptr|                            Printer formatting]]<br/>
+
-
[[Printermnemonics|                  Printer mnemonics]]  <br/>
+
-
[[Inputprintfile|                    PRINTFILE statement]]</br>
+
-
[[Priority|                          PRIORITY$ system variable]]<br/>
+
-
[[Procedure|                        Procedure Division]]<br/>
+
-
[[Dospseudofunctions|                Pseudo DOS Functions]]<br/>
+
-
[[Sortpseudocode|                    Pseudocode for in-memory sort]]<br/>
+
-
[[Sortpseudocodemerge|              Pseudocode for sort/merge]]<br/>
+
-
[[Pstat|                            PSTAT function]]<br/>
+
-
[[Pushfont|                        (Push Font) mnemonic]]<br/>
+
-
[[Queryclipboard|                  (Query Clipboard) mnemonic]]<br/>
+
-
[[Quick|                            Quick reference guide]]<br/>
+
-
[[Radiobuttonoff|                  (Radio Button Off) mnemonic]]<br/>
+
-
[[Radiobuttonon|                    (Radio Button On) mnemonic]]<br/>
+
-
[[Rb|                              (RB) mnemonic]]<br/>
+
-
[[Rc|                              (RC) mnemonic]]<br/>
+
-
[[Rd|                              (RD) mnemonic]]<br/>
+
-
[[Dosread|                          Read from a DOS file]]<br/>
+
-
[[Read|                              Read from a InternetBasic file]]<br/>
+
-
[[Readmouse|                        (Read Mouse) mnemonic]]<br/>
+
-
[[Read|                              READ statement]]<br/>
+
-
[[Readingmouse|                      Reading the mouse]]<br/>
+
-
[[Recnum|                            RECNUM function]]<br/>
+
-
[[Extract|                          Record locking]]<br/>
+
-
[[Rectangle|                        (Rectangle) mnemonic]]<br/>
+
-
[[Redrawnotify|                    (Redraw Notify) mnemonic]]<br/>
+
-
[[Regularcursor|                    Regular cursor display]]<br/>
+
-
[[Relationaloperators|              Relational Operators]]<br/>
+
-
[[Mc|                                Remember cursor position (MC)]]<br/>
+
-
[[Dosrmdir|                          Remove DOS subdirectory]]<br/>
+
-
[[Rename|                            Rename a InternetBasic file]]<br/>
+
-
[[Rename|                            RENAME statement]]<br/>
+
-
[[Renamefile|                      (RenameFile) mnemonic]]<br/>
+
-
[[Requestid|                        (Request ID) mnemonic]]<br/>
+
-
[[Resetscreen|                      (Reset Screen) mnemonic]]<br/>
+
-
[[Rc|                                Restore cursor position (RC)]]<br/>
+
-
[[Restorescreen|                    (Restore Screen) mnemonic]]<br/>
+
-
[[Restorewaitcursor|                (RestoreWaitCursor) mnemonic]]<br/>
+
-
[[Http_Overview|                    Retrieving web pages via HTTP]]<br/>
+
-
[[Return|                            RETURN statement]]<br/>
+
-
[[Rewrite|                          REWRITE statement]]<br/>
+
-
[[Adjust|                            Right justify function]]<br/>
+
-
[[Rj|                                Right justify mark (RJ)]]<br/>
+
-
[[Rb|                                Ring bell (RB)]]<br/>
+
-
[[Rj|                              (RJ) mnemonic]]<br/>
+
-
[[Rnd|                              RND function]]<br/>
+
-
[[Rd|                                Roll down (RD)]]<br/>
+
-
[[Ru|                                Roll up (RU)]]<br/>
+
-
[[Round|                            ROUND statement]]<br/>
+
-
[[Round|                            Rounding data fields]]<br/>
+
-
[[Roundrect|                        (RoundRect) mnemonic]]<br/>
+
-
[[Rpos|                              RPOS function]]<br/>
+
-
[[Rsub|                              RSUB function]]<br/>
+
-
[[Ru|                              (RU) mnemonic]]<br/>
+
-
[[Cmdmode|                          RUN compiler command]]<br/>
+
-
[[Run|                              RUN statement]]<br/>
+
-
[[Run|                              Running a program overlay]]<br/>
+
-
[[Enter|                            Running a subprogram]]<br/>
+
-
[[Runstate|                          RUNSTATE system variable]]<br/>
+
-
[[Samplemouseopen|                  Sample mouse open program]]<br/>
+
-
[[Windowsample|                      Sample window program]]<br/>
+
-
[[Satisfyinput|                    (SatisfyInput) mnemonic]]<br/>
+
-
[[Savescreen|                      (Save Screen) mnemonic]]<br/>
+
-
[[Sb|                              (SB) mnemonic]]<br/>
+
-
[[Scancodesoff|                    (Scan Codes Off) mnemonic]]<br/>
+
-
[[Scancodes|                        Scan Codes]]<br/>
+
-
[[Screencolors|                      Screen Colors]]<br/>
+
-
[[Fmtvideo|                          Screen formatting]]<br/>
+
-
[[Screen|                          (Screen) mnemonic]]<br/>
+
-
[[Searchfile|                        SearchFile statement]]<br/>
+
-
[[Secure|                            SECURE statement]]<br/>
+
-
[[Secure|                            Security]]<br/>
+
-
[[Selectfont|                      (SelectFont) mnemonic]]<br/>
+
-
[[Selecthatchbrush|                (SelectHatchBrush) mnemonic]]<br/>
+
-
[[Selectpen|                        (SelectPen) mnemonic]]<br/>
+
-
[[Selectsolidbrush|                (SelectSolidBrush) mnemonic]]<br/>
+
-
[[Selectsysfont|                    (SelectSysFont) mnemonic]]<br/>
+
-
[[Selectwindowex|                  (SelectWindowEx) mnemonic]]<br/>
+
-
[[Dosmessageall|                    Sending a message to all terminals]]<br/>
+
-
[[Dosmessage|                        Sending a message to another terminal]]<br/>
+
-
[[Smtp_Smtpcommands|                Sending e-mail via SMTP]]<br/>
+
-
[[Sequent|                          Sequential file]]<br/>
+
-
[[Serial|                            Serial gateway]]<br/>
+
-
[[Emailserver|                      (Server) mnemonic]]<br/>
+
-
[[Set|                              SET directive]]<br/>
+
-
[[Setprinterinfo|                  (Set Printer Info) mnemonic]]<br/>
+
-
[[Setrop2|                          (Set ROP2) mnemonic]]<br/>
+
-
[[Setwindowcaption|                (Set Window Caption) mnemonic]]<br/>
+
-
[[Setbit|                            SETBIT function]]<br/>
+
-
[[Setbkcolor|                      (SetBkColor) mnemonic]]<br/>
+
-
[[Setbkmode|                        (SetBkMode) mnemonic]]<br/>
+
-
[[Setdiralias|                      (SetDirAlias) mnemonic]]<br/>
+
-
[[Setfmt|                            SetFormat statement]]<br/>
+
-
[[Setglobal|                        SetGlobal statement]]<br/>
+
-
[[Setorientation|                  (SetOrientation) mnemonic]]<br/>
+
-
[[Setpapersize|                    (SetPaperSize) mnemonic]]<br/>
+
-
[[Setsessionprinter|                (SetSessionPrinter) mnemonic]]<br/>
+
-
[[Settextalign|                    (SetTextAlign) mnemonic]]<br/>
+
-
[[Settextcolor|                    (SetTextColor) mnemonic]]<br/>
+
-
[[Settingwcolors|                    Setting window colors (legacy windows)]]<br/>
+
-
[[Sf|                              (SF) mnemonic]]<br/>
+
-
[[Sgn|                              SGN function]]<br/>
+
-
[[Shelltodos|                      (Shell to DOS) mnemonic]]<br/>
+
-
[[Shellexecute|                    (ShellExecute) mnemonic]]<br/>
+
-
[[Shellexecutewait|                (ShellExecuteWait) mnemonic]]<br/>
+
-
[[Showcursor|                      (Show Cursor) mnemonic]]<br/>
+
-
[[Showmousecursor|                  (Show Mouse Cursor) mnemonic]]<br/>
+
-
[[Shmousecursor|                    Show/hide the mouse cursor]]<br/>
+
-
[[Singlekeytransmit|                (Single Key Transmit) mnemonic]]<br/>
+
-
[[Sl|                                Skip n lines]]<br/>
+
-
[[Sl|                              (SL=n) mnemonic]]<br/>
+
-
[[Sortdescendingmerge|              Sort descending sort/merge]]<br/>
+
-
[[Sortgateway|                      Sort gateway]]<br/>
+
-
:[[sortascending|Sort ascending in memory]]<br/>
+
-
:[[sortascendingmerge|Sort ascending sort/merge]]<br/>
+
-
:[[sortbeginmerge|Sort begin sort/merge]]<br/>
+
-
:[[sortdescending|Sort descending in memory]]<br/>
+
-
:[[sortascendingmerge|ort descending sort/merge]]<br/>
+
-
:[[sortpointer|Sort move pointer to top]]<br/>
+
-
[[sortrecordlength|Sort record length]]<br/>
+
-
[[Compilercommands|                  SOURCE command]]<br/>
+
-
[[Source|                            Source Program Divisions]]<br/>
+
-
[[Compchar|                          Special characters (compiler)]]<br/>
+
-
[[Specialcharacters|                Special Characters (in IB source code)]]
+
-
:[[specialcharacters#ampersand|Ampersand (&)]]<br/>
+
-
:[[specialcharacters#asterisk|Asterisk (*)]]<br/>
+
-
:[[specialcharacters#atsign|At sign (@)]]<br/>
+
-
:[[specialcharacters#comma|Comma (,)]]<br/>
+
-
:[[specialcharacters#decimalpoint|Decimal point (.)]]<br/>
+
-
:[[specialcharacters#dollarsign|Dollar sign ($)]]<br/>
+
-
:[[specialcharacters#equalsign|Equal sign (=)]]<br/>
+
-
:[[specialcharacters#exclamation|Exclamation mark (!)]]<br/>
+
-
:[[specialcharacters#greaterthansign|Greater than sign (&gt;)]]<br/>
+
-
:[[specialcharacters#lessthansign|Less than sign (&lt;)]]<br/>
+
-
:[[specialcharacters#minussign|Minus sign (-)]]<br/>
+
-
:[[specialcharacters#numbersign|Number sign (#)]]<br/>
+
-
:[[specialcharacters#parentheses|Parentheses]]<br/>
+
-
:[[specialcharacters#plussign|Plus sign (+)]]<br/>
+
-
:[[specialcharacters#quotes|Quotation marks]]<br/>
+
-
:[[specialcharacters#semicolon|Semicolon (;)]]<br/>
+
-
:[[specialcharacters#slash|Division sign (/)]]<br/>
+
-
:[[specialcharacters#slash|Slash sign (/)]]<br/>
+
-
:[[specialcharacters#underline|Underline character]]<br/>
+
-
[[Spoolmessage|                    (Spool Message) mnemonic]] <br/>
+
-
[[Sqrt|                              SQRT function]]<br/>
+
-
[[Sqrt|                              Square root]]<br/>
+
-
[[Ssb|                              (SSB) mnemonic]]<br/>
+
-
[[Sslrelay|                          SSL Relay]]<br/>
+
-
[[Sb|                                Start background (SB)]]<br/>
+
-
[[Sf|                                Start foreground (SF)]]<br/>
+
-
[[Ssb|                              Start suppressed background (SSB)]]<br/>
+
-
[[Stmtcont|                          Statement Continuation]]<br/>
+
-
[[Linelabl|                          Statement labels]]<br/>
+
-
[[Proceduredivisionstatements|      Statement Summary]]<br/>
+
-
[[Sts|                              Status function (STS)]]<br/>
+
-
[[Stdkeyboardoff|                  (Std Keyboard Off) mnemonic]]<br/>
+
-
[[Stdkeyboardon|                    (Std Keyboard On) mnemonic]]<br/>
+
-
[[Stop|                              STOP statement]]<br/>
+
-
[[Storecontrol|                    (StoreControl) mnemonic]]<br/>
+
-
[[Str|                              STR function]]<br/>
+
-
[[String|                            STRING function]]<br/>
+
-
[[Strings|                          String Manipulation]]<br/>
+
-
[[Stringoperator|                    String Operator]]<br/>
+
-
[[Strip|                            STRIP function]]<br/>
+
-
[[Stripl|                            STRIPL function]]<br/>
+
-
[[Stripr|                            STRIPR function]]<br/>
+
-
[[Sts (Winsock Gateway)|            STS function (Winsock gateway)]]<br/>
+
-
[[Sts|                              STS function]]<br/>
+
-
[[Sub|                              SUB function]]<br/>
+
-
[[Emailsubject|                    (Subject) mnemonic]]<br/>
+
-
[[Subprog|                          Subprograms]]<br/>
+
-
[[Gosub|                            Subroutines]]<br/>
+
-
[[Arrays|                            Subscripted variables (arrays)]]<br/>
+
-
[[Swap|                              SWAP function]]<br/>
+
-
[[Switchsession|                    (Switch Session) mnemonic]]<br/>
+
-
[[Set|                              Symbolic constants]]<br/>
+
-
[[Syspart|                          SYSPART$ system variable]]<br/>
+
-
[[Date|                              System date]]<br/>
+
-
[[Errorsub|                          SYSTEM parameter, ERRORSUB]]<br/>
+
-
[[Errorto|                          SYSTEM parameter, ERRORTO]]<br/>
+
-
[[Escapesub|                        SYSTEM parameter, ESCAPESUB]]<br/>
+
-
[[Escapeto|                          SYSTEM parameter, ESCAPETO]]<br/>
+
-
[[Systemsymbolicconstants|          System Symbolic Constants]]<br/>
+
-
[[Time|                              System time]]<br/>
+
-
[[Systemvariables|                  System variables (chart)]]<br/>
+
-
[[Systvar|                          System variables]]<br/>
+
-
[[Ports|                            TCP/IP Ports used by Signature Products]]<br/>
+
-
[[Term|                              TERM$ system variable]]<br/>
+
-
[[Term|                              Terminal identification]]<br/>
+
-
[[Terminate|                        Terminate a partition]]<br/>
+
-
[[Terminate|                        TERMINATE statement]]<br/>
+
-
[[Testbit|                          TESTBIT function]]<br/>
+
-
[[Text|                              Text files]]<br/>
+
-
[[Emailtext|                        (Text) mnemonic]]<br/>
+
-
[[Textout|                          (TextOut) mnemonic]]<br/>
+
-
[[Time|                              TIME$ system variable]]<br/>
+
-
[[Tm|                              (TM) mnemonic]]<br/>
+
-
[[Emailto|                          (To) mnemonic]]<br/>
+
-
[[Hidemousecursor|                  Touch-sensitive screens]]<br/>
+
-
[[Tp|                              (TP) mnemonic]]<br/>
+
-
[[Tr|                              (TR) mnemonic]]<br/>
+
-
[[Tm|                                Transmit mark (TM)]]<br/>
+
-
[[Tp|                                Transmit stop mark (TP)]]<br/>
+
-
[[Transparentcolor|                (Transparent Color) mnemonic]]<br/>
+
-
[[Tr|                                Transparent printing mode]]<br/>
+
-
[[True|                              TRUE]]<br/>
+
-
[[Et|                                Typewriter mode]]<br/>
+
-
[[Ucase|                            UCASE function]]<br/>
+
-
[[Underamp|                          Underscore and ampersand]]<br/>
+
-
[[Unlock|                            UNLOCK statement]]<br/>
+
-
[[Unlock|                            Unlocking a InternetBasic file]]<br/>
+
-
[[Unset|                            UNSET directive]]<br/>
+
-
[[Update|                            UPDATE statement]]<br/>
+
-
[[Update|                            Updating data records]]<br/>
+
-
[[Ucase|                            Upper case conversion]]<br/>
+
-
[[Uppercaseinput|                  (Upper Case Input) mnemonic]]<br/>
+
-
[[Use|                              USE directive]]<br/>
+
-
[[Usefile|                          Usefiles]]<br/>
+
-
[[Usinghelp|                        Using the Automatic Help Feature]]<br/>
+
-
[[Compile|                          Using the IB Compiler]]<br/>
+
-
[[Varclass|                          Variable classification]]<br/>
+
-
[[Varlen|                            Variable length]]<br/>
+
-
[[Varnames|                          Variable names]]<br/>
+
-
[[Vartypes|                          Variable types]]<br/>
+
-
[[Verifyfile|                      (Verify File) mnemonic]]<br/>
+
-
[[Version|                          Version number]]<br/>
+
-
[[Version|                          VERSION$ system variable]]<br/>
+
-
[[Vidcodes|                          Video Control Codes]]<br/>
+
-
[[Fmtvideo|                          Video Screen Formatting Overview]]<br/>
+
-
[[Wait|                              WAIT statement]]<br/>
+
-
[[Wakeup|                            WAKEUP statement]]<br/>
+
-
[[Wallpaperbitmap|                  (Wallpaper Bitmap) mnemonic]]<br/>
+
-
[[Wallpaperclear|                  (Wallpaper Clear) mnemonic]]<br/>
+
-
[[Wallpapercolor|                  (Wallpaper Color) mnemonic]]<br/>
+
-
[[Wallpaperremove|                  (Wallpaper Remove) mnemonic]]<br/>
+
-
[[Wc|                              (WC) mnemonic]]<br/>
+
-
[[Whohasfile|                      (Who Has File) mnemonic]]<br/>
+
-
[[Windowmemory|                      Window memory (legacy windows)]]<br/>
+
-
[[Windowtitlebackground|            (Window Title Background) mnemonic]]<br/>
+
-
[[Windowtitleforeground|            (Window Title Foreground) mnemonic]]<br/>
+
-
[[Windowsfilemnemonics|              Windows file mnemonics]]<br/>
+
-
[[Windowsprintermnemonics|          Windows printer mnemonics]] <br/>
+
-
[[Windowsprinting|                  Windows printing]]<br/>
+
-
[[Winsockerrorcodes|                Windows Sockets Error Codes]]<br/>
+
-
[[Windowstitle|                      Windows title line]]<br/>
+
-
[[Gatewaysubroutine|                Winsock Gateway Subroutine]]<br/>
+
-
[[Winsockgatewayoverview|            Winsock Gateway]]<br/>
+
-
[[Write|                            WRITE statement]]<br/>
+
-
[[Doswrite|                          Write to a DOS file]]<br/>
+
-
[[Write|                            Write to a InternetBasic file]]<br/>
+
-
[[Wc|                                Write to control line (WC)]]<br/>
+
-
[[Ecomet|                            XAP gateway (eComet)]]<br/>
+
-
[[Longyear|                          Year (system variable)]]<br/>
+

Latest revision as of 14:55, 12 February 2014

XAP Gateway Internals

There are 2 major parts to the XAP technology. The first part is what we call the CGI server and the second is what we call the XAP Gateway.

The CGI Server

The CGI server listens on the port configured for it. It expects to receive connections using the http protocol. It then performs the following steps:

   It receives and assembles a whole browser request.
   It parses the individual parts of this request, splitting out the following components:
   The CGI Environment variables.
   Any Cookies that the browser may have sent.
   Any query strings that the browser may have sent.
   It then writes these items into a Keyed File* (called the XAP environment file), so that a user program can access them quickly.
       CGI environment variables are written to the keyed file such that the key name is the environment variable name with dots instead of underlines separating words of the name, ie HTTP_USER_AGENT would become HTTP.USER.AGENT.
       Cookie names are preceded with a "C." so that a cookie by the name of "my cookie" would be written as "C.MY COOKIE".
       Likewise, query strings are preceded with a "Q." so that a query string by the name of "credit card number" would be written as "Q.CREDIT CARD NUMBER".
   If an appropriate cookie was present in the request, the CGI server establishes the context data for the connection.
   It then launches the Internet Basic program designated by the SCRIPT.NAME environment variable. The program inherits a connection to the browser through the XAP gateway, any context items established in step 4 above, and the keyed file produced in step 3 above.

Note: Any mention of "files" in this document does not necessarily mean "disk files". Files may reside in memory or disk depending on performance/sharing issues.


The XAP Gateway

The XAP Gateway acts in response to commands included in the Internet Basic program launched by the CGI Server. The interface is very easy to learn because it contains relatively few basic commands:

   Write – the program may write data to the browser through the gateway.
   If no previous data has been written to the XAP Gateway, the XAP Gateway will generate a standard HTML header before sending the data to the browser. The program is free to modify this behavior through a control explained below. Otherwise, the data will be sent directly to the browser. All data is buffered for best performance.
   Control – the program may send various controls that cause the gateway to perform actions meaningful to the program. These will be described below.
   Status – the program can get various pieces of information from the gateway by the use of a simple status function.
   Close – When the LUN pointing to the XAP Gateway is closed, all buffered data is sent to the browser, Context data is filed away for future connections, and the connection to the browser is gracefully closed.
   The XAP environment file is also used as part of the interface between the program and the XAP gateway. The program can read browser request data from this file as explained above. It may also write information that will eventually be written to the browser as explained below.


XAP Gateway Controls

Most of the power of the XAP Gateway is embedded in the various Controls that the program may send to it. The Control statement looks like a standard function in the language:

Syntax:

Result-string = CONTROL(LUN,Control.String [,EXCP=exception.routine])

The CONTROL statement sends the specified control-string to the specified logical unit number. In the case of the XAP Gateway, the Logical Unit Number or "LUN" is always 0 (zero).

The CONTROL statement also reads the result field from the input buffer and places it in the result-string. A plus sign (+) in the first byte of the result-string indicates that the control function was performed successfully. A minus sign (-) in the first byte indicates that the control was not performed successfully. The remaining bytes of the result-string contain text describing the success or failure of the control function.

The CONTROL statement performs the same function as the following statements:

FILE (LUN) CTL=control-string

INPUT (LUN) result-string

Here are the controls that may be sent to the XAP gateway. Where string constants are used in the examples, string expressions may also be used.

   TYPE – sets a MIME type to the browser. As explained above if no TYPE control is sent, the type is assumed to be HTML and the appropriate header is sent to the browser..
   Result-string = CONTROL (0,"TYPE 0") notifies the XAP gateway that the program will subsequently write its own MIME type header.
   result-string = CONTROL(0,"TYPE 1") tells the XAP Gateway to set the mime type to "text/html"
   result-string = CONTROL(0,"TYPE 2") tells the XAP Gateway to set the mime type to "text/plain"
   Result-string = CONTROL (0,"TYPE 3") tells the XAP Gateway to set the mime type to "text/plain" and supply automatic carriage return line feeds following every write.
   COOKIE – sends a cookie to the browser. This control must be sent before any other data is sent to the browser because the cookie information is part of the header.
   The syntax is as follows:
   A$ = CONTROL (0,'COOKIE cookie-name=cookie-value,time-period')
   Where time-period is the specified length of time for the cookie to be stored in the browser.
   The format for time period is:
   +nM = n minutes into the future
   +nH = n hours into the future
   +nD = n days into the future
   For example, to make the CUSTOMERNUMBER=123456789 cookie stay in the browser system for 25 days, you would use the following statement:
   A$ = CONTROL(0,'COOKIE CUSTOMERNUMBER=123456789,+25D')
   REDIRECT – Sends the appropriate commands to the browser so that it will automatically connect to the URL contained in the REDIRECT control. This control must be sent before any other data is sent to the browser because the redirect information is part of the header.
   For example, if you wanted your program to redirect the browser to www.signature.net, you would use the following statement:
   A$ = CONTROL(0,'REDIR http://www.signature.net')
   OPEN – performs a "test open" of the file contained in the control to validate whether it is present. This file may be a template file, html file, image file or any file. The named file is opened, and the handle is saved for further operations using that file.
   For example, if you wanted your program to send the image contained in the file "c:\images\logo.jpg" to the browser, you would use the following command:
   A$ = CONTROL (0,'OPEN C:\IMAGES\LOGO.JPG')
   After the execution of this control, the result string A$ would contain "+OK" if the file was successfully opened, or "-ERR error opening path" if the file could not be found.
   SEND – Sends the file referred to in the control to the browser. The file is sent to the browser in the fastest way possible. The SEND control may specify a path pointing to the file to be sent --
   A$ = CONTROL (0,'SEND C:\IMAGES\LOGO.JPG')
   or optionally, if no path is specified --
   A$ = CONTROL (0,'SEND')
   the XAP gateway will send a file previously opened by the OPEN control as specified above.
   PUSH – Flushes the output buffer contained in the XAP gateway to the browser for debugging purposes or to implement "server push" actions.
   MERGE – Merges data from a template file named in the control with data contained in the CGI Environment file, Then sends the resultant merged data stream to the browser. Merge is the most powerful of all of the controls. It merges selected data from the CGI environment file with a template file (or a section of a template file) and sends the resulting web page to the browser.

The syntax for the MERGE control may take several forms. The general description of the merge command is:

A$ = CONTROL (LUN,’MERGE Path-name |"." [,SECTION Section-name])

As you can see, the MERGE command takes an optional path name and an optional section name. Here is how Comet processes a MERGE command.

       Comet first determines if there is a path name specified, or a dot, meaning use the last file either opened from a previous MERGE command or an OPEN command. If a Path name was supplied, that file is opened.
       Comet then determines whether a SECTION name was supplied. If a Section name was specified, Comet searches the file for a string of characters such as:
       <!—BEGIN Section-nameà
       If found, the file pointer is set just beyond this string, causing Comet to read data from this point on. If no such string was found, Comet starts reading the e file from the first byte.
       If a section was specified in the control statement, Comet then searches the file for an end-of-section string. This string is of the form:
       <!—END Section-nameà
       If such a string is found, a pointer is set to the character just prior to the opening character of this string. This pointer marks the last character sent from the file on this Merge command. If no such string is found, the ending pointer is set to the last character of the file.
       Comet then searches the file starting at the current file pointer for an indicator marking data to be inserted. At the current time, this marker is a pair of stars (**).
       If such a marker is found, all data is streamed from the file to the Browser up to this marker.
       Comet then searches the file for an ending indicator. At the current time this is also a pair of stars (**). If such a marker is found, all characters between the beginning and ending markers (including the **’s) is assembled into a Key to be used in a keyed read on LUN 1. If the read is successful, the data record resulting from this keyed read is streamed to the browser.
       If the keyed read was unsuccessful, the first * of the beginning marker is sent to the browser and the process is repeated from step d. above.
       Once the entire file or section has been streamed to the browser, the control command is completed.

It should be noted that the syntax used for the begin and end indicators denotes HTML comments. Thus the markers would not be visible in the html page if the browser displayed them.

It should also be noted that even though the operations above look like operations on a file, the data is really read into memory and streamed from there for performance reasons.

Following are two lessons from a tutorial which deal with the MERGE command:

This lesson and the next one are the most important lessons in the eComet tutorial. In this lesson, you will learn how to merge live Comet data into stored HTML documents.

Let us repeat that last part (for emphasis): you can merge live Comet data into a stored HTML document in order to make a dynamic return page.


Here's how it works:

First, create an XAP-ready HTML document. In the locations where you want to include a merge field, surround the field name with double asterisks.

Here's a sample HTML file. We've included one merge field named **TODAY**.

<HTML>

<HEAD>

<TITLE>

Sample merge document

</TITLE>

</HEAD>

<BODY>

This is a sample document.

Today's date is **TODAY**.

</BODY>

</HTML>

For the sake of this example, let's suppose we saved this file on drive C: and named the file TODAY.HTM.

Next, write an Internet Basic program that does two things:

1.Writes the merge field(s) to the CGI Environment File, using the double-asterisk field name as the key

2.Merges the HTML document with the CGI Environment File via the MERGE command

Here's some sample code to show you how this works:

LENGTH 10 & LOCAL TODAY$

CGIDATA: FORMAT TODAY$

TODAY$ = '06/08/2000'

WRITE (1,CGIDATA) KEY='**TODAY**' ! Write merge field

A$ = CONTROL(0,'MERGE C:\TODAY.HTM') ! Merge the HTML file

The WRITE statement writes a record to the CGI Environment file (remember, this file is automatically opened on Logical Unit Number 1 when the XAP program is started). The key is the same as the merge field name in the HTML document (i.e.,**TODAY**).

The MERGE command merges the HTML document (C:\TODAY.HTM) with any merge field(s) contained in the CGI Environment File. In this example, there's only one merge field.

The result is a web page that contains "06/08/2000" in the exact location where "**TODAY**" was contained in the stored document.

Here are some important notes:

The MERGE command is very similar to the SEND command (i.e., it sends a stored document from the eComet system to the browser.

The merge field(s) can appear anywhere in the stored document. This means that you can merge Comet data into places where you want data to appear, and you can also merge HTML commands into a stored document (to change the appearance of a web page for a particular user, for example).

Here's another example. Remember the program (from Lesson 2) that displayed several Comet system variables? Well, we've rewritten that example using the MERGE command.

First, we created an HTML document and included several merge fields. The "raw" document is named systvar.htm. Take a look at the HTML source code and notice the merge fields (**PARTITION** and the others).

Next, we created an Internet Basic program that writes the desired merge records to the CGI Environment File. Look at the following source code and notice the WRITE statements.

!---------------------------------------------------------------------

!

! *** Main program

!

A$ = DSTAT('CL1') ! Refresh TIME$

!

OPEN (10) '#CGICTRL' ! Open CGI control file

READ (10,HTMLPATH) KEY='**HTMLPATH**' ! Get HTML path

HTMLPATH$ = STRIP(HTMLPATH$) ! Strip blanks

CLOSE (10)

!

! *** Write merge fields to CGI file

!

OUTPUT$ = PARTITION$ ! Partition #

WRITE (1,OUTPUT) KEY='**PARTITION**' ! Write record

!

OUTPUT$ = TIME$ ! System time

WRITE (1,OUTPUT) KEY='**TIME**' ! Write record

!

OUTPUT$ = DATE$ ! System date

WRITE (1,OUTPUT) KEY='**DATE**' ! Write record

!

OUTPUT$ = LONGYEAR$ ! 4-digit year

WRITE (1,OUTPUT) KEY='**LONGYEAR**' ! Write record

!

OUTPUT$ = VERSION$ ! Version #

WRITE (1,OUTPUT) KEY='**VERSION**' ! Write record

!

! *** Merge the CGI file with the HTML file, and send the results

!

MERGESTRING$ = 'MERGE '+HTMLPATH$ + 'systvar.htm' ! Build MERGE string

A$ = CONTROL(0,MERGESTRING$) ! Merge

!

KILL PARTITION$

Note

The MERGE command may also be executed via the FILE statement, as shown here:

FILE (0) CTL='MERGE ______________'

HTML file name


In Lesson 3, we showed you how to send multiple stored documents to the web browser with the SEND command. The MERGE command can be used to do the same thing.

For example, here's a program segment that sends 3 stored documents via the MERGE command:

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3x.htm')

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3y.htm')

A$ = CONTROL(0,'MERGE c:\ecomet\html\sample3z.htm')

Please note these differences between SEND and MERGE:

The MERGE command invokes the merge feature, while the SEND command does not

There's another very important difference between SEND and MERGE. The MERGE command can send sections of an HTML document. The sections are user-defined portions of the HTML file.

These sections are defined via the HTML comment tag and some XAP-specific keywords within each comment. Here's an example:


This is a section of HTML code. This

section includes text as well as HTML

commands.

This whole section is defined by the BEGIN and END statements, which are contained within HTML comments. The browser ignores the BEGIN and END statements, since they're contained within HTML comments. However, the MERGE command uses the BEGIN and END commands to defined a section of the file. This section is called ABC123. Assume that you saved the above HTML file as: c:\ecomet\html\test.htm Here's how you would send this section of the HTML file via the MERGE command: A$ = CONTROL(0,'MERGE c:\ecomet\html\test.htm SECTION ABC123') Some important notes: There is no limit to the number of sections you may define The first section in an HTML document does not require a statement The final section does not require an statement. No blank spaces are allowed at the beginning of these commands (i.e., inside of the " statement and an statement. Content outside of those boundaries will not be sent to the browser. The next example is based on the sample program you saw in Lesson 4. In this case, we will be merging data from a Comet data file, the DLRS file, into a stored HTML document. The HTML document will be divided into 3 sections, named TOP, MIDDLE, and BOTTOM. The TOP section will contain the initial HTML commands and text for the top portion of the web page. Since this is the first section, we don't need a statement. <HTML> <HEAD> <TITLE> Comet Dealers </TITLE> </HEAD> <BODY BGCOLOR="FFFFFF">

Comet Dealers


Here is a list of Comet dealers.

This data is contained in a

Comet keyed file named DLRS.

The DEMO11B program reads records

from that file and displays the

complete list of names.

The MIDDLE section will be very short. In this section, we will include a merge field named **DEALER**, followed by a line break tag (
):

    • DEALER**

By itself, the MIDDLE section does not look very impressive. Just wait until you see the way we use Internet Basic to merge data into this section! The BOTTOM section will contain the final HTML commands for our sample web page: </BODY> </HTML> We'll save the above file and name it: c:\ecomet\html\dealers.htm Now all we have to do is write an Internet Basic program that sends the 3 sections (and merged data) to the web browser. The first MERGE command will send SECTION TOP: A$ = CONTROL(0,'MERGE c:\ecomet\html\dealers.htm SECTION TOP') The next part of the Internet Basic program will READ data from the DLRS file, WRITE a key to the CGI Environment File, and MERGE SECTION MIDDLE. These steps will be repeated for all of the records in the DLRS file: OPEN (10) 'DLRS' ReadMore: READ (10,DEALERINFO) EXCP=AllDone WRITE (1,DEALERINFO) KEY='**DEALER**' A$ = CONTROL(0,'MERGE . SECTION MIDDLE') GOTO ReadMore Notice that the key value (**DEALER**) matches the merge field in the HTML file. Also notice that the MERGE command contains a different format than before. If you are merging more than one section of an HTML file, you only have to specify the file name once (on the first MERGE command). After that, you can use the period (.) to represent the HTML file name. The period is both a coding shortcut and a way to get faster performance from the MERGE command. Once an HTML file has been opened and read into memory, there's no need to re-open and re-read it. Thus, the period refers to a document that is already in memory. The final section the program closes the data file and sends the BOTTOM section of the HTML file: AllDone: CLOSE (10) A$ = CONTROL(0,'MERGE . SECTION BOTTOM') KILL PARTITION$ Here's something to Think About As we mentioned above, merge fields can appear anywhere in an HTML file, including HTML commands and parameters. For example, you could include a merge field where you would normally include a hard-coded parameter, as in the BACKGROUND portion of the BODY tag: <BODY BACKGROUND="**PICTURE**"> Then, from within an Internet Basic program, you could define a specific background graphic simply by writing the **PICTURE** key to the CGI Environment File and merging it with your HTML file. PICTURE: FORMAT PICTURE$ . PICTURE$ = "SAMPLE.GIF" WRITE (1,PICTURE) KEY="**PICTURE**" A$ = CONTROL(0,'MERGE HTML-document SECTION section-name') You could use this technique to good effect, for example, by displaying a unique background graphic for each customer who uses your web site. You could determine who's who by reading a persistent cookie (assuming you had already sent one to the browser), getting unique data from that cookie (a customer number, let's say), and using that data to read a GIF or JPG file name from a keyed file. Then you could write that file name to the CGI Environment File and merge it into an HTML file, as shown in the code segment above. This would result in a very personalized web site for each of your customers.
  • Keyed Files
Keyed files provide direct access to the data records. Comet stores data for keyed files in two DOS disk files. One DOS file stores the data records in their entered order, and a "key tree" file stores the record keys in ascending ASCII order. An individual record may be retrieved using this identifier using the KEY= parameter of the READ (or associated input) statement. A keyed file may also be read in key-sequential order; records are retrieved in ascending sorted key order. The index for a keyed file is a string field from 1 to 64 characters long. When the file is created, the key length is specified. So is the record length; this value ranges from 1 to 1,024 bytes, and is fixed for each record in the file. Because of the ease of use and advantages of direct access, keyed files are the most common types of data files used in Internet Basic applications. When an Internet Basic program opens a keyed file, the Comet operating system assigns a unique file pointer to the file. Each user opening the file is assigned a unique pointer, allowing multiple users to access data from the same file at the same time. To avoid data integrity problems when more than one user is accessing a file, Internet Basic provides a record locking mechanism. The EXTRACT statement is used to read and lock individual data records. As a user accesses records in a keyed file, the file pointer keeps track of the current location. When the file is opened, the pointer is located at the record associated with the first key. If the records are retrieved without an index, the pointer moves along in ascending ASCII order of the key values (i.e., in key-sequential order). When a record is accessed directly using an index, the pointer is moved to the associated position. If no record is found matching the specified index, an exception occurs, but the pointer is located at the index following the requested index value. From this point, the program could retrieve records in sequence (without an index), or retrieve another record from the file using another index value. Keyed files may also be accessed with a numeric index. In this case, the index value is used to specify the record number in the file in record number sequence (rather than in key sequence). Application notes: Since Key trees are built using "Balanced B Tree" structures, access to specific records is very fast. Depending on key length, access to a single record in a file of several million records may only take 3 or 4 reads from the underlying file system. A keyed file provides the most convenient way to randomly access a file. Therefore, most Internet Basic programs use keyed files to store data records. When a record is deleted from a keyed file, the vacated space is automatically reused by the file to store subsequent records. This advantage is another reason why keyed files are predominant in Internet Basic applications.
Personal tools