home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / vlngthio.src < prev   
Encoding:
Text File  |  1988-05-03  |  117.8 KB  |  3,298 lines

  1. ::::::::::
  2. messageio.pro
  3. ::::::::::
  4. -------- SIMTEL20 Ada Software Repository Prologue ------------
  5. --                                                           -*
  6. -- Unit name    :  MESSAGE_IO
  7. -- Version      :  1.0
  8. -- Author       :  Patrick Kopson 
  9. --              : Texas Instruments  
  10. --              :  
  11. --              :  
  12. -- DDN Address  :  WOODY%TI-EG@CSNET-RELAY
  13. -- Copyright    :  (c) 1985
  14. -- Date created :  01 APR 85
  15. -- Release date :  03 DEC 85
  16. -- Last update  :  03 DEC 85
  17. -- Machine/System Compiled/Run on :  VAX 11/785  VMS 4.1
  18. --                                   DEC Ada
  19. --                                                           -*
  20. ---------------------------------------------------------------
  21. --                                                           -*
  22. -- Keywords     : Text_Messages  
  23. ----------------:
  24. --
  25. -- Abstract     :  
  26. --   This package is used for sending messages to the defaut
  27. --   output file.  See the visible part for the details of the
  28. --   structure of the messages.  Minor changes to this package
  29. --   (including making the length of certain fields generic 
  30. --   parameters) would make this package much more versatile.
  31. ----------------:  
  32. --                                                           -*
  33. ------------------ Revision history ---------------------------
  34. --                                                           -*
  35. -- DATE         VERSION    AUTHOR                  HISTORY
  36. -- 12/3/85      1.0         Patrick Kopson          Initial Release
  37. --                                                           -*
  38. ------------------ Distribution and Copyright -----------------
  39. --                                                           -*
  40. -- This prologue must be included in all copies of this software.
  41. --
  42. -- This software is copyright by the author.
  43. --
  44. -- This software is released to the Ada community.
  45. -- This software is released to the Public Domain (note:
  46. --   software released to the Public Domain is not subject
  47. --   to copyright protection).
  48. -- Restrictions on use or distribution:  NONE
  49. --                                                           -*
  50. ------------------ Disclaimer ---------------------------------
  51. --                                                           -*
  52. -- This software and its documentation are provided "AS IS" and
  53. -- without any expressed or implied warranties whatsoever.
  54. -- No warranties as to performance, merchantability, or fitness
  55. -- for a particular purpose exist.
  56. --
  57. -- Because of the diversity of conditions and hardware under
  58. -- which this software may be used, no warranty of fitness for
  59. -- a particular purpose is offered.  The user is advised to
  60. -- test the software thoroughly before relying on it.  The user
  61. -- must assume the entire risk and liability of using this
  62. -- software.
  63. --
  64. -- In no event shall any person or organization of people be
  65. -- held responsible for any direct, indirect, consequential
  66. -- or inconsequential damages or lost profits.
  67. --                                                           -*
  68. -------------------END-PROLOGUE--------------------------------
  69. ::::::::::
  70. messageio.ada
  71. ::::::::::
  72. -------- SIMTEL20 Ada Software Repository Prologue ------------
  73. --                                                           -*
  74. -- Unit name    :  MESSAGE_IO
  75. -- Version      :  1.0
  76. -- Author       :  Patrick Kopson 
  77. --              : Texas Instruments  
  78. --              :  
  79. --              :  
  80. -- DDN Address  :  WOODY%TI-EG@CSNET-RELAY
  81. -- Copyright    :  (c) 1985
  82. -- Date created :  01 APR 85
  83. -- Release date :  03 DEC 85
  84. -- Last update  :  03 DEC 85
  85. -- Machine/System Compiled/Run on :  VAX 11/785  VMS 4.1
  86. --                                   DEC Ada
  87. --                                                           -*
  88. ---------------------------------------------------------------
  89. --                                                           -*
  90. -- Keywords     : Text_Messages  
  91. ----------------:
  92. --
  93. -- Abstract     :  
  94. --   This package is used for sending messages to the defaut
  95. --   output file.  See the visible part for the details of the
  96. --   structure of the messages.  Minor changes to this package
  97. --   (including making the length of certain fields generic 
  98. --   parameters) would make this package much more versatile.
  99. ----------------:  
  100. --                                                           -*
  101. ------------------ Revision history ---------------------------
  102. --                                                           -*
  103. -- DATE         VERSION    AUTHOR                  HISTORY
  104. -- 12/3/85      1.0         Patrick Kopson          Initial Release
  105. --                                                           -*
  106. ------------------ Distribution and Copyright -----------------
  107. --                                                           -*
  108. -- This prologue must be included in all copies of this software.
  109. --
  110. -- This software is copyright by the author.
  111. --
  112. -- This software is released to the Ada community.
  113. -- This software is released to the Public Domain (note:
  114. --   software released to the Public Domain is not subject
  115. --   to copyright protection).
  116. -- Restrictions on use or distribution:  NONE
  117. --                                                           -*
  118. ------------------ Disclaimer ---------------------------------
  119. --                                                           -*
  120. -- This software and its documentation are provided "AS IS" and
  121. -- without any expressed or implied warranties whatsoever.
  122. -- No warranties as to performance, merchantability, or fitness
  123. -- for a particular purpose exist.
  124. --
  125. -- Because of the diversity of conditions and hardware under
  126. -- which this software may be used, no warranty of fitness for
  127. -- a particular purpose is offered.  The user is advised to
  128. -- test the software thoroughly before relying on it.  The user
  129. -- must assume the entire risk and liability of using this
  130. -- software.
  131. --
  132. -- In no event shall any person or organization of people be
  133. -- held responsible for any direct, indirect, consequential
  134. -- or inconsequential damages or lost profits.
  135. --                                                           -*
  136. -------------------END-PROLOGUE--------------------------------
  137.  
  138. package MESSAGE_IO is 
  139. -------------------------------------------------------------------------------
  140. ----                                                                       ----
  141. --                          VISIBLE TYPE DECLARATIONS                        --
  142. ----                                                                       ----
  143. -------------------------------------------------------------------------------
  144.  
  145.               -- Type Declarations for module name abbreviations:
  146.  
  147. type Character_Type is ( 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  148.                          'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  149.                          'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
  150.                          'Y', 'Z', '_' );
  151.      --| Allowable characters for module names and message id's
  152.  
  153. Name_Length : constant := 6;
  154.      --| Largest number of characters per module name abbreviation
  155.  
  156. type Name_Range_Type is range  1 .. Name_Length;
  157.      --| Type for length of module name abbreviations
  158.  
  159. type Name_Array_Type is array ( Name_Range_Type ) of Character_Type;
  160.      --| Type for module name abbreviations 
  161.  
  162.  
  163.               -- Type Declarations for message id's:
  164.  
  165. Max_Message_Id : constant := 8;
  166.      --| Largest number of characters per message id
  167.  
  168. type Message_Id_Range_Type is range 1 .. Max_Message_Id;
  169.      --| Type for lengths of message id's
  170.  
  171. type Message_Id_Array_Type is 
  172.          array ( Message_Id_Range_Type ) of Character_Type;
  173.      --| Type for message id's
  174.  
  175.  
  176.               -- Type Declarations for priority kinds:
  177.  
  178. type Priority_Kind_Type is ( Alevel, Slevel, Tell_All );
  179.      --| Each message must have one of these priority kinds associated with it
  180.  
  181. subtype Priority_Kind_Constrained_Type is 
  182.          Priority_Kind_Type range Alevel ..  Slevel;
  183.      --| Constrained type of priority kinds for defining priority levels
  184.  
  185.  
  186.               -- Type Declarations for text line extensions:
  187.  
  188. Text_Array_Length : constant := 32767;
  189.      --| Largest number of text lines allowed
  190.  
  191. Text_Line_Length : constant := 72;
  192.      --| Largest number of characters per line of text
  193.  
  194. subtype Text_Line_Type is string ( 1 .. Text_Line_Length );
  195.      --| Type for text lines
  196.  
  197. type Text_Array_Length_Type is range  0 .. Text_Array_Length;
  198.      --| Type for length of text array
  199.  
  200. type Text_Array_Type 
  201.      is array ( Text_Array_Length_Type range <> ) of Text_Line_Type;
  202.      --| Type for text line extensions 
  203.  
  204. Null_Text_Array : constant Text_Array_Type ( 1 .. 0 ) := 
  205.                            ( 1 .. 0 => ( 1 .. Text_Line_Length => ' ' ) );
  206.      --| Constant for null text lines
  207.  
  208.  
  209.               -- Type Declarations for progress report headline 
  210.               --                       and message structure line:
  211.  
  212. Required_Text_Line_Length : constant := 40;
  213.      --| Maximum length for required text line
  214.  
  215. subtype Required_Text_Line_Type is string ( 1 .. Required_Text_Line_Length );
  216.      --| Type for required text line
  217.  
  218.  
  219. type Severity_Level is ( Note, Warning, Error, Failure );
  220.  
  221.  
  222. -------------------------------------------------------------------------------
  223. ----                                                                       ----
  224. --                          PACKAGE ENTRY POINTS                             --
  225. ----                                                                       ----
  226. -------------------------------------------------------------------------------
  227.  
  228.  
  229. procedure DISPLAY_PROGRESS ( Report_Title : in Required_Text_Line_Type;
  230.                              Report_Text  : in Text_Array_Type 
  231.                                                := Null_Text_Array;
  232.                              Priority     : in Severity_Level := Failure );
  233.  
  234.    --|    OVERVIEW
  235.    --|       When the priority of the progress message, given by Priority, is
  236.    --|       higher than or equal to the lowest priority defined for the Slevel
  237.    --|       priority kind, this procedure outputs to the message file the 
  238.    --|       progress report headline given by Report_Title, the wall clock date
  239.    --|       and time, and if specified, the optional extension text given by 
  240.    --|       Report_Text.
  241.    --|    REQUIRES
  242.    --|       The message file must be open.
  243.    --|    EFFECTS
  244.    --|       The report title, wall clock date and time is written to the 
  245.    --|       message file.  The report text is selected for output, when
  246.    --|       specified, when the priority is higher than or equal to the
  247.    --|       lowest priority defined for the Slevel priority kind.  The
  248.    --|       format of the report output is the following:
  249.    --|             
  250.    --|       CONTROL:             <report_title>       hh:mm:ss dd-MMM-yyyy
  251.    --|
  252.    --|    o    [                         .                              ]
  253.    --|    p    [                         .                              ]
  254.    --|    t    [                         .                              ]
  255.    --|    i    [             . . . <report_text> . . .                  ]
  256.    --|    o    [                         .                              ] 
  257.    --|    n    [                         .                              ]
  258.    --|    a    [                         .                              ]
  259.    --|    l    [                         .                              ]
  260.    --|
  261.    --|    RAISES
  262.    --|       MSIO_MESSAGE_FILE_DISASTER
  263.    --|    ERRORS
  264.    --|       If the message file has not been opened, or if the capacity 
  265.    --|       of the message file has been exceeded, or if the output 
  266.    --|       operation could not be completed because of a malfunction 
  267.    --|       of  the  underlying  system,  then  the  exception 
  268.    --|       MSIO_MESSAGE_FILE_DISASTER will be raised.  
  269.    --|    NA
  270.    --|       MODIFIES
  271.  
  272.  
  273. procedure DISPLAY_MSG
  274.        ( Module_Abbr             : in Name_Array_Type;
  275.          Message_Id              : in Message_Id_Array_Type;
  276.          Message_Text_Standard   : in Required_Text_Line_Type;
  277.          Message_Text_Addition   : in Text_Array_Type    := Null_Text_Array;
  278.          Priority_Kind           : in Priority_Kind_Type := Tell_All;
  279.          Priority                : in Severity_Level     := Note );
  280.                                                                
  281.    --|    OVERVIEW
  282.    --|       When the priority of the message given by Priority, is higher than
  283.    --|       or equal to the lowest priority defined for the priority kind given
  284.    --|       by Priority_Kind, this procedure outputs to the message file the 
  285.    --|       module abbreviation given by Module_Abbr, the message 
  286.    --|       identification given by Message_Id, the structure line, which 
  287.    --|       contains the required portion of the message, given by 
  288.    --|       Message_Text_Standard, and if specified, the optional extension
  289.    --|       text given by Message_Text_Addition.
  290.    --|    REQUIRES
  291.    --|       The message file must be open.  
  292.    --|    EFFECTS
  293.    --|       The module abbreviation, the message identification, the
  294.    --|       priority, and the standard message text are output to the
  295.    --|       message file.  Messages with priority higher than or equal 
  296.    --|       to the lowest priority level defined for a particilar 
  297.    --|       priority kind are selected for output to the output file.  
  298.    --|       If the lowest priority is not defined, then all messages 
  299.    --|       will be output.  If the priority kind, given by Priority_Kind, 
  300.    --|       is Tell_All, then the given message is output regardless of 
  301.    --|       priority.  The format of the message output looks like the 
  302.    --|       following:
  303.    --|             
  304.    --|       <module_abbr> - <priority> - <message_id>  <message_text_standard>
  305.    --|
  306.    --|    o    [                         .                                ]
  307.    --|    p    [                         .                                ]
  308.    --|    t    [                         .                                ]
  309.    --|    i    [         . . . <message_text_addition> . . .              ]
  310.    --|    o    [                         .                                ] 
  311.    --|    n    [                         .                                ]
  312.    --|    a    [                         .                                ]
  313.    --|    l    [                         .                                ]
  314.    --|
  315.    --|    RAISES
  316.    --|       MSIO_MESSAGE_FILE_DISASTER
  317.    --|    ERRORS
  318.    --|       If the message file has not been opened, or if the capacity 
  319.    --|       of the message file has been exceeded, or if the output 
  320.    --|       operation could not be completed because of a malfunction 
  321.    --|       of  the  underlying  system,  then  the  exception 
  322.    --|       MSIO_MESSAGE_FILE_DISASTER will be raised.  
  323.    --|    NA
  324.    --|       MODIFIES
  325.  
  326.  
  327. procedure DEFINE_LOWEST_PRIORITY 
  328.                       ( Priority_Kind  : in Priority_Kind_Constrained_Type;
  329.                         Priority_Level : in Severity_Level );
  330.  
  331.    --|    OVERVIEW
  332.    --|       This procedure allows the lowest reportable message priority,
  333.    --|       given by Priority_Level, to be defined for a priority kind,
  334.    --|       given by Priority_Kind.
  335.    --|    EFFECTS
  336.    --|       The lowest priority for a priority kind is defined.
  337.    --|    NA
  338.    --|       REQUIRES, RAISES, ERRORS
  339.  
  340.  
  341. procedure CLOSE_MESSAGE_FILE;
  342.  
  343.    --|    OVERVIEW
  344.    --|       This procedure closes the message file.
  345.    --|    REQUIRES
  346.    --|       The message file must be open.
  347.    --|    EFFECTS
  348.    --|       A message indicating that the message file is closed 
  349.    --|       is written to the message file, then the message file 
  350.    --|       is closed.
  351.    --|    RAISES
  352.    --|       MSIO_MESSAGE_FILE_DISASTER
  353.    --|    ERRORS
  354.    --|       If the message file is not open, then the exception 
  355.    --|       MSIO_MESSAGE_FILE_DISASTER will be raised.
  356.    --|    NA
  357.    --|       MODIFIES
  358.  
  359.  
  360.  
  361. -- Exceptions raised by Message file I/O package
  362.  
  363. MSIO_MESSAGE_FILE_DISASTER : exception;
  364.  
  365. end MESSAGE_IO;
  366.  
  367.  
  368. -------------------------------------------------------------------------------
  369. ----                                                                       ----
  370. --                         MESSAGE I/O PACKAGE BODY                          --
  371. ----                                                                       ----
  372. -------------------------------------------------------------------------------
  373.  
  374. with TEXT_IO;
  375. with CALENDAR;
  376.  
  377. package body MESSAGE_IO is 
  378. -------------------------------------------------------------------------------
  379. ----                                                                       ----
  380. --                       INTERNAL TYPES AND OBJECTS                          --
  381. ----                                                                       ----
  382. -------------------------------------------------------------------------------
  383. subtype Date_And_Time_Type is STRING (1 .. 22);
  384.  
  385. type Priority_Array_Type is 
  386.      array (Priority_Kind_Constrained_Type) of Severity_Level;
  387.  
  388. Lowest_Priority_Array :  Priority_Array_Type 
  389.                       := (Severity_Level'First, Severity_Level'First);
  390.  
  391. File_Is_Closed : BOOLEAN := false;
  392.  
  393. -------------------------------------------------------------------------------
  394. ----                                                                       ----
  395. --                           INTERNAL PROCEDURES                             --
  396. ----                                                                       ----
  397. -------------------------------------------------------------------------------
  398. function Character_Equivalent_Of 
  399.          (Char : in     Character_Type) return Character is
  400.  
  401.    --| OVERVIEW
  402.    --|   This function returns the character equivalent of an item of
  403.    --|   type Character_Type.
  404.    --|
  405.    --| ALGORITHM
  406.    --|   Use Char as an index to an array of characters to select the result.
  407.  
  408.    type Character_Array_Type is array (Character_Type) of Character;
  409.  
  410.    Character_Array : Character_Array_Type := ('A', 'B', 'C', 'D', 'E', 'F', 'G',
  411.                                               'H', 'I', 'J', 'K', 'L', 'M', 'N',
  412.                                               'O', 'P', 'Q', 'R', 'S', 'T', 'U',
  413.                                               'V', 'W', 'X', 'Y', 'Z', '_');
  414.    begin
  415.      return Character_Array (Char);
  416.    end Character_Equivalent_Of;
  417.  
  418.  
  419. function Date_And_Time return Date_And_Time_Type is
  420.  
  421.    --| OVERVIEW
  422.    --|   This function returns the date and time from the wall clock
  423.    --|   as a STRING so that TEXT_IO can write it to the message file.
  424.    --|
  425.    --| EFFECTS
  426.    --|   The date and time are returned as a string with the following format:
  427.    --|   " hh:mm:ss  dd-MMM-yyy".
  428.    --|
  429.    --| NA
  430.    --|  REQUIRES, ERRORS, RAISES, MODIFIES
  431.    --|
  432.    --| ALGORITHM
  433.    --|   After getting the Year, Month, Day and Seconds from CALENDAR
  434.    --|   subprograms, derive Hour, Minute and Sec from Seconds.
  435.    --|   Then insert the images of these values into the result string.
  436.  
  437.    Result : STRING(1 .. 22) := " hh:mm:ss  dd-MMM-yyyy";
  438.  
  439.    Seconds_Per_Minute : constant := 60;
  440.    Seconds_Per_Hour   : constant := 3600;
  441.  
  442.    subtype Hour_Number   is INTEGER range 0 .. 23;
  443.    subtype Minute_Number is INTEGER range 0 .. 59;
  444.    subtype Sec_Number    is INTEGER range 0 .. 59;
  445.  
  446.    Date : CALENDAR.Time;
  447.  
  448.    Year    : CALENDAR.Year_Number;
  449.    Month   : CALENDAR.Month_Number;
  450.    Day     : CALENDAR.Day_Number;
  451.    Seconds : CALENDAR.Day_Duration;
  452.  
  453.    Hour   : Hour_Number;
  454.    Minute : Minute_Number;
  455.    Sec    : Sec_Number;
  456.  
  457.    begin
  458.       Date := CALENDAR.Clock;
  459.       CALENDAR.Split (Date,
  460.                       Year,
  461.                       Month,
  462.                       Day,
  463.                       Seconds);
  464.       Hour    := INTEGER(Seconds) / Seconds_Per_Hour;
  465.       Seconds := CALENDAR.Day_Duration (INTEGER(Seconds) rem Seconds_Per_Hour);
  466.       Minute  := INTEGER(Seconds) / Seconds_Per_Minute;
  467.       Sec     := INTEGER(Seconds) rem Seconds_Per_Minute;
  468.  
  469.       Result(18 .. 22) := CALENDAR.Year_Number'IMAGE (Year);
  470.       Result(18) := '-';
  471.  
  472.       case Month is
  473.          when 1 => Result(15 .. 17) := "JAN";
  474.          when 2 => Result(15 .. 17) := "FEB";
  475.          when 3 => Result(15 .. 17) := "MAR";
  476.          when 4 => Result(15 .. 17) := "APR";
  477.          when 5 => Result(15 .. 17) := "MAY";
  478.          when 6 => Result(15 .. 17) := "JUN";
  479.          when 7 => Result(15 .. 17) := "JUL";
  480.          when 8 => Result(15 .. 17) := "AUG";
  481.          when 9 => Result(15 .. 17) := "SEP";
  482.          when 10 => Result(15 .. 17) := "OCT";
  483.          when 11 => Result(15 .. 17) := "NOV";
  484.          when 12 => Result(15 .. 17) := "DEC";
  485.       end case;
  486.  
  487.       if  (Day < 10)  then
  488.          Result(12 .. 13) := CALENDAR.Day_Number'IMAGE (Day);
  489.          Result(12) := '0';
  490.       else
  491.          Result(11 .. 13) := CALENDAR.Day_Number'IMAGE (Day);
  492.       end if;
  493.        
  494.       if  (Sec < 10)  then
  495.          Result(8 .. 9) := Sec_Number'IMAGE (Sec);
  496.          Result(8) := '0';
  497.       else
  498.          Result(7 .. 9) := Sec_Number'IMAGE (Sec);
  499.          Result(7) := ':';
  500.       end if;
  501.        
  502.       if  (Minute < 10)  then
  503.          Result(5 .. 6) := Minute_Number'IMAGE (Minute);
  504.          Result(5) := '0';
  505.       else
  506.          Result(4 .. 6) := Minute_Number'IMAGE (Minute);
  507.          Result(4) := ':';
  508.       end if;
  509.        
  510.       if  (Hour < 10)  then
  511.          Result(2 .. 3) := Hour_Number'IMAGE (Hour);
  512.          Result(2) := '0';
  513.       else
  514.          Result(1 .. 3) := Hour_Number'IMAGE (Hour);
  515.       end if;
  516.        
  517.       return Result;
  518.    end Date_And_Time;
  519.   
  520.  
  521. -------------------------------------------------------------------------------
  522. ----                                                                       ----
  523. --                          PACKAGE ENTRY POINTS                             --
  524. ----                                                                       ----
  525. -------------------------------------------------------------------------------
  526. procedure DISPLAY_PROGRESS 
  527.           ( Report_Title : in Required_Text_Line_Type;
  528.             Report_Text  : in Text_Array_Type := Null_Text_Array;
  529.             Priority     : in Severity_Level := Failure ) is
  530.  
  531.    --| OVERVIEW
  532.    --|   If the priority (Priority) is higher than or equal to the lowest
  533.    --|   priority defined for the Slevel priority kind, this procedure
  534.    --|   outputs the progress report headline (Report_Title) and the wall
  535.    --|   clock date and time to the message file on one line with the 
  536.    --|   optional extension text (Report_Text), if specified, on following
  537.    --|   lines.
  538.    --|
  539.    --| ALGORITM
  540.    --|   . . . 
  541.  
  542.    begin
  543.      if File_Is_Closed then
  544.         TEXT_IO.PUT 
  545.                 ("***** MESSAGE_IO.Display_Progress called with file closed.");
  546.         raise MSIO_MESSAGE_FILE_DISASTER;
  547.      end if;
  548.    
  549.      if  ( Priority >= Lowest_Priority_Array(Slevel) )  then
  550.         TEXT_IO.PUT ("CONTROL:   ");
  551.         TEXT_IO.PUT (Report_Title);
  552.         TEXT_IO.PUT ("     ");
  553.         TEXT_IO.PUT (Date_And_Time);
  554.         TEXT_IO.NEW_LINE;
  555.  
  556.         for Line in  Report_Text'RANGE(1)  loop
  557.            TEXT_IO.PUT ("   ");
  558.            TEXT_IO.PUT ( Report_Text(Line) ); 
  559.            TEXT_IO.NEW_LINE;
  560.         end loop;
  561.      end if;
  562.  
  563.    exception
  564.      when others => raise MSIO_MESSAGE_FILE_DISASTER;
  565.  
  566.    end DISPLAY_PROGRESS;  
  567.  
  568.  
  569. procedure DISPLAY_MSG
  570.           ( Module_Abbr             : in Name_Array_Type;
  571.             Message_Id              : in Message_Id_Array_Type;
  572.             Message_Text_Standard   : in Required_Text_Line_Type;
  573.             Message_Text_Addition   : in Text_Array_Type    := Null_Text_Array;
  574.             Priority_Kind           : in Priority_Kind_Type := Tell_All;
  575.             Priority                : in Severity_Level     := Note ) is
  576.                                                                
  577.    --| OVERVIEW
  578.    --|   If the priority (Priority) is higher than or equal to the lowest
  579.    --|   priority defined for the priority kind (Priority_Kind), this
  580.    --|   procedure outputs the module abbreviation (Module_Abbr), the
  581.    --|   priority (Priority), the message identification (Message_Id), and
  582.    --|   the structure line which contains the required portion of the 
  583.    --|   message (Message_Text_Standard) to the message file on one line,
  584.    --|   with the optional extension text (Message_Text_Addition), if 
  585.    --|   specified, on following lines.
  586.    --|
  587.    --| NOTES
  588.    --|   The Lowest_Priority for each priority kind is initialized
  589.    --|   to the lowest possible value; so there is no need to check
  590.    --|   whether it is undefined (indicating that we should write the 
  591.    --|   message regardless of the priority).
  592.    --|
  593.    --| ALGORITHM
  594.    --|   After writing the Module_Abbr, Priority, Message_ID and 
  595.    --|   Message_Text_Standard, we check the Priority and Priority_Kind
  596.    --|   to determine whether we must write the Message_Text_Addition.
  597.  
  598.    begin
  599.      if File_Is_Closed then
  600.         TEXT_IO.PUT ("***** MESSAGE_IO.Display_Msg called with file closed.");
  601.         raise MSIO_MESSAGE_FILE_DISASTER;
  602.      end if;
  603.  
  604.      if  ( Priority_Kind =  Tell_All ) or else 
  605.          ( Priority >= Lowest_Priority_Array(Priority_Kind) )  then
  606.         for Char in Module_Abbr'RANGE loop
  607.            TEXT_IO.PUT ( Character_Equivalent_Of(Module_Abbr(Char)) );
  608.         end loop;
  609.         TEXT_IO.PUT (" - ");
  610.         case Priority is
  611.            when Note    => TEXT_IO.PUT ( "NOTE" );
  612.            when Warning => TEXT_IO.PUT ( "WARNING" );
  613.            when Error   => TEXT_IO.PUT ( "ERROR" );
  614.            when Failure => TEXT_IO.PUT ( "FAILURE" );
  615.            when others  => TEXT_IO.PUT ( "OTHER" );
  616.         end case;
  617.         TEXT_IO.PUT (" - ");
  618.         for Char in Message_ID'RANGE loop
  619.            TEXT_IO.PUT ( Character_Equivalent_Of(Message_ID(Char)) );
  620.         end loop;
  621.         TEXT_IO.PUT (" - ");
  622.         TEXT_IO.PUT (Message_Text_Standard);
  623.         TEXT_IO.NEW_LINE;
  624.  
  625.         for Line in  Message_Text_Addition'RANGE(1)  loop
  626.            TEXT_IO.PUT ("   ");
  627.            TEXT_IO.PUT ( Message_Text_Addition(Line) ); 
  628.            TEXT_IO.NEW_LINE;
  629.         end loop;
  630.      end if;
  631.  
  632.    exception
  633.      when others => raise MSIO_MESSAGE_FILE_DISASTER;
  634.  
  635.    end DISPLAY_MSG;
  636.  
  637.  
  638. procedure DEFINE_LOWEST_PRIORITY 
  639.           ( Priority_Kind  : in Priority_Kind_Constrained_Type;
  640.             Priority_Level : in Severity_Level ) is
  641.  
  642.    --| OVERVIEW
  643.    --|   This procedure allows the lowest reportable message priority,
  644.    --|   given by Priority_Level, to be defined for a priority kind,
  645.    --|   given by Priority_Kind.
  646.    --| 
  647.    --| ALGORITHM
  648.    --|   Set the specified lowest_priprity to Priority_Level
  649.  
  650.    begin
  651.      Lowest_Priority_Array (Priority_Kind) := Priority_Level;
  652.    exception
  653.      when others => raise MSIO_MESSAGE_FILE_DISASTER;
  654.    end DEFINE_LOWEST_PRIORITY;
  655.  
  656.  
  657. procedure CLOSE_MESSAGE_FILE is
  658.  
  659.    --| OVERVIEW
  660.    --|   This procedure closes the message file.
  661.    --|
  662.    --| NOTES   
  663.    --|   The standard output file can not be closed!
  664.    --|   Therefore, this procedure will write a closing message
  665.    --|   (including the wall clock date and time) to the message file 
  666.    --|   and then quit.
  667.    --|
  668.    --| ALGORITHM
  669.    --|   Write a closing message to the file.
  670.    --|   Close the default output file if possible.
  671.  
  672.    Close_File : TEXT_IO.File_Type;
  673.  
  674.    begin
  675.      TEXT_IO.PUT ("Mesage File closed at    ");
  676.      TEXT_IO.PUT (Date_And_Time);
  677.      TEXT_IO.NEW_LINE;
  678.      File_Is_Closed := true;
  679.    exception
  680.      when others => raise MSIO_MESSAGE_FILE_DISASTER;
  681.    end CLOSE_MESSAGE_FILE;
  682.  
  683. end MESSAGE_IO;
  684. ::::::::::
  685. vlengthio.pro
  686. ::::::::::
  687. -------- SIMTEL20 Ada Software Repository Prologue ------------
  688. --                                                           -*
  689. -- Unit name    :  VARIABLE_LENGTH_DIRECT_IO
  690. -- Version      :  1.0
  691. -- Author       :  Patrick Kopson 
  692. --              : Texas Instruments  
  693. --              :  
  694. --              :  
  695. -- DDN Address  :  WOODY%TI-EG@CSNET-RELAY
  696. -- Copyright    :  (c) 1985
  697. -- Date created :  01 APR 85
  698. -- Release date :  03 DEC 85
  699. -- Last update  :  03 DEC 85
  700. -- Machine/System Compiled/Run on :  VAX 11/785  VMS 4.1
  701. --                                   DEC Ada
  702. --                                                           -*
  703. ---------------------------------------------------------------
  704. --                                                           -*
  705. -- Keywords     : DIRECT_IO, Varible-Length IO  
  706. ----------------:
  707. --
  708. -- Abstract     :  
  709. --|   This is a package similar to DIRECT_IO that operates on records of
  710. --|   variable length.  The body of this package may use CAIS utilities
  711. --|   in the future.
  712. --|
  713. --|   This package allows the user to write elements of differing lengths to a
  714. --|   single direct access file.  This package can be used to write data
  715. --|   of all types to a single file (with the aid of UNCHECKED_CONVERSION).
  716. --|   The DATA_FILE_IO package in the Ada repository serves as an example of
  717. --|   how this can be accomplished.
  718. --|
  719. --|   This package also reduces the time-per-byte-of-data-transfered by reducing
  720. --|   the number of calls to the run time libraray routines associated with the
  721. --|   predefined generic package DIRECT_IO.  This is accomplished by placing
  722. --|   many incoming records into a large buffer and then writng the entire 
  723. --|   buffer to an external file as a single element (vice versa for reading).
  724. --|   Bytes_Per_Block, the only generic parameter for this package, determines 
  725. --|   the size (in bytes) of this buffer.
  726. ----------------:  
  727. --                                                           -*
  728. ------------------ Revision history ---------------------------
  729. --                                                           -*
  730. -- DATE         VERSION    AUTHOR                  HISTORY
  731. -- 12/3/85      1.0         Patrick Kopson          Initial Release
  732. --                                                           -*
  733. ------------------ Distribution and Copyright -----------------
  734. --                                                           -*
  735. -- This prologue must be included in all copies of this software.
  736. --
  737. -- This software is copyright by the author.
  738. --
  739. -- This software is released to the Ada community.
  740. -- This software is released to the Public Domain (note:
  741. --   software released to the Public Domain is not subject
  742. --   to copyright protection).
  743. -- Restrictions on use or distribution:  NONE
  744. --                                                           -*
  745. ------------------ Disclaimer ---------------------------------
  746. --                                                           -*
  747. -- This software and its documentation are provided "AS IS" and
  748. -- without any expressed or implied warranties whatsoever.
  749. -- No warranties as to performance, merchantability, or fitness
  750. -- for a particular purpose exist.
  751. --
  752. -- Because of the diversity of conditions and hardware under
  753. -- which this software may be used, no warranty of fitness for
  754. -- a particular purpose is offered.  The user is advised to
  755. -- test the software thoroughly before relying on it.  The user
  756. -- must assume the entire risk and liability of using this
  757. -- software.
  758. --
  759. -- In no event shall any person or organization of people be
  760. -- held responsible for any direct, indirect, consequential
  761. -- or inconsequential damages or lost profits.
  762. --                                                           -*
  763. -------------------END-PROLOGUE--------------------------------
  764. ::::::::::
  765. vlengthio.ada
  766. ::::::::::
  767. --------------------------------------------------------------------------------
  768. ----                                                                        ----
  769. --                     VARIABLE LENGTH DIRECT IO PACKAGE                      --
  770. ----                                                                        ----
  771. --------------------------------------------------------------------------------
  772. -------- SIMTEL20 Ada Software Repository Prologue ------------
  773. --                                                           -*
  774. -- Unit name    :  generic package VARIABLE_LENGTH_DIRECT_IO
  775. --                                 ( Bytes_Per_Block : in Positive )
  776. -- Version      :  1.0
  777. -- Author       :  Patrick Kopson 
  778. --              : Texas Instruments  
  779. --              :  
  780. --              :  
  781. -- DDN Address  :  WOODY%TI-EG@CSNET-RELAY
  782. -- Copyright    :  (c) 1985
  783. -- Date created :  01 APR 85
  784. -- Release date :  03 DEC 85
  785. -- Last update  :  03 DEC 85
  786. -- Machine/System Compiled/Run on :  VAX 11/785  VMS 4.1
  787. --                                   DEC Ada
  788. --                                                           -*
  789. ---------------------------------------------------------------
  790. --                                                           -*
  791. -- Keywords     : DIRECT_IO, Varible-Length IO  
  792. ----------------:
  793. --
  794. -- Abstract     :  
  795. --|   This is a package similar to DIRECT_IO that operates on records of
  796. --|   variable length.  The body of this package may use CAIS utilities
  797. --|   in the future.
  798. --|
  799. --|   This package allows the user to write elements of differing lengths to a
  800. --|   single direct access file.  This package can be used to write data
  801. --|   of all types to a single file (with the aid of UNCHECKED_CONVERSION).
  802. --|   The DATA_FILE_IO package in the Ada repository serves as an example of
  803. --|   how this can be accomplished.
  804. --|
  805. --|   This package also reduces the time-per-byte-of-data-transfered by reducing
  806. --|   the number of calls to the run time libraray routines associated with the
  807. --|   predefined generic package DIRECT_IO.  This is accomplished by placing
  808. --|   many incoming records into a large buffer and then writng the entire 
  809. --|   buffer to an external file as a single element (vice versa for reading).
  810. --|   Bytes_Per_Block, the only generic parameter for this package, determines 
  811. --|   the size (in bytes) of this buffer.
  812. ----------------:  
  813. --                                                           -*
  814. ------------------ Revision history ---------------------------
  815. --                                                           -*
  816. -- DATE         VERSION    AUTHOR                  HISTORY
  817. -- 12/3/85      1.0         Patrick Kopson          Initial Release
  818. --                                                           -*
  819. ------------------ Distribution and Copyright -----------------
  820. --                                                           -*
  821. -- This prologue must be included in all copies of this software.
  822. --
  823. -- This software is copyright by the author.
  824. --
  825. -- This software is released to the Ada community.
  826. -- This software is released to the Public Domain (note:
  827. --   software released to the Public Domain is not subject
  828. --   to copyright protection).
  829. -- Restrictions on use or distribution:  NONE
  830. --                                                           -*
  831. ------------------ Disclaimer ---------------------------------
  832. --                                                           -*
  833. -- This software and its documentation are provided "AS IS" and
  834. -- without any expressed or implied warranties whatsoever.
  835. -- No warranties as to performance, merchantability, or fitness
  836. -- for a particular purpose exist.
  837. --
  838. -- Because of the diversity of conditions and hardware under
  839. -- which this software may be used, no warranty of fitness for
  840. -- a particular purpose is offered.  The user is advised to
  841. -- test the software thoroughly before relying on it.  The user
  842. -- must assume the entire risk and liability of using this
  843. -- software.
  844. --
  845. -- In no event shall any person or organization of people be
  846. -- held responsible for any direct, indirect, consequential
  847. -- or inconsequential damages or lost profits.
  848. --                                                           -*
  849. -------------------END-PROLOGUE--------------------------------
  850.  
  851. with SYSTEM;
  852. with DIRECT_IO;
  853. with IO_EXCEPTIONS;
  854.  
  855. generic
  856.  
  857.   Bytes_Per_Block : in Positive;
  858.  
  859. package VARIABLE_LENGTH_DIRECT_IO is
  860. -------------------------------------------------------------------------------
  861. ----                                                                       ----
  862. --                       VISIBLE TYPE DECLARATIONS                           --
  863. ----                                                                       ----
  864. -------------------------------------------------------------------------------
  865.  
  866.   type File_Type is limited private;
  867.     --|  An external file to be written to or read from using this package
  868.     --|  must have an object of File_Type associated with it.  The File_Type
  869.     --|  object is passed in for all routines.
  870.  
  871.   type Internal_File_Pointer_Type is private;
  872.     --|  Objects of Internal_File_Pointer_Type are used as an index into a
  873.     --|  file.  An open file has a current index, which is of this type, and is
  874.     --|  used by the read and write operations.  When a file is opened, the
  875.     --|  current index is set to the index of the first record.
  876.  
  877.   type File_Mode_Type is (In_Mode, Inout_Mode);
  878.     --|  An open file must have one of these modes associated with it.  A file
  879.     --|  of mode In_Mode is for reading only.  A file of mode Inout_Mode is for
  880.     --|  reading and writing.
  881.  
  882.   subtype Non_Negative is Integer range 0 .. Integer'LAST;
  883.  
  884.   type Storage_Unit_Type is array ( 1 .. SYSTEM.Storage_Unit ) of Boolean;
  885.   pragma PACK (Storage_Unit_Type);
  886.     --|  Records will be built up from storage units.
  887.  
  888.   All_False : constant Storage_Unit_Type := ( 1..SYSTEM.Storage_Unit => False);
  889.  
  890.   type Record_Type is array ( Non_Negative range <> ) of Storage_Unit_Type;
  891.     --|  Objects to be read or written must be of Record_Type.
  892.  
  893.   type Block_Count_Type is new Non_Negative;
  894.     --|  This type is used for objects representing the number 
  895.     --|  of data blocks in a file.
  896. ---------------------------------------------------------------------------
  897. ----                                                                   ----
  898. --                         PACKAGE ENTRY POINTS                          --
  899. ----                                                                   ----
  900. ---------------------------------------------------------------------------
  901.  
  902.   procedure CREATE
  903.             ( File : in out File_Type;
  904.               Mode : in     File_Mode_Type := Inout_Mode;
  905.               Name : in     string := "";
  906.               Form : in     string := "" );
  907.  
  908.     --| OVERVIEW
  909.     --|   This procedure is similar the CREATE routine of the DIRECT_IO
  910.     --|   package and is used to establish a new external file, with the
  911.     --|   given name, mode and form, and to associate this external file 
  912.     --|   with the given file.  The given file is left open.  The default
  913.     --|   access mode is Inout_Mode.
  914.     --|
  915.     --| REQUIRES
  916.     --|   The given file must not be open already.
  917.     --|
  918.     --| EFFECTS
  919.     --|   External file is created with given name and form.  File is opened.
  920.     --|
  921.     --| RAISES
  922.     --|   VLIO_STATUS_ERROR, VLIO_NAME_ERROR, VLIO_USE_ERROR
  923.     --|
  924.     --| ERRORS
  925.     --|   If the given file is already open, the exception VLIO_STATUS_ERROR
  926.     --|   is raised.  
  927.     --|   If the string given as Name does not allow the identification of an 
  928.     --|   external file, the exception VLIO_NAME_ERROR is raised.
  929.     --|   If for the specified mode, the environment does not support creating 
  930.     --|   an external file with the given name and form, the exception 
  931.     --|   VLIO_USE_ERROR is raised.
  932.     --|
  933.     --| NA
  934.     --|   MODIFIES
  935.  
  936.  
  937.   procedure OPEN
  938.             ( File : in out File_Type;
  939.               Mode : in     File_Mode_Type;
  940.               Name : in     string;
  941.               Form : in     string := "" );
  942.  
  943.     --| OVERVIEW
  944.     --|   This procedure is used similarly to the open routine in the
  945.     --|   DIRECT_IO package.  The given file is associated with an existing
  946.     --|   external file having the given name and form, and sets the current
  947.     --|   mode of the given file to the given mode.  The given file is left
  948.     --|   open and the current read index and write index are set to the 
  949.     --|   index of the first record.
  950.     --|
  951.     --| REQUIRES
  952.     --|   The given file must exist and not be open already.
  953.     --|
  954.     --| EFFECTS
  955.     --|   Associates file name with external file and opens external file.
  956.     --|   Current read index and write index are set to first record.
  957.     --|
  958.     --| RAISES
  959.     --|   VLIO_STATUS_ERROR, VLIO_NAME_ERROR, VLIO_USE_ERROR
  960.     --|
  961.     --| ERRORS
  962.     --|   If the given file is already open, the exception VLIO_STATUS_ERROR
  963.     --|   is raised.  
  964.     --|   If the string given as Name does not allow the identification of an 
  965.     --|   external file, (in particular, if the external file with the given 
  966.     --|   name doesn't exist), the exception VLIO_NAME_ERROR is is raised.  
  967.     --|   If, for the specified mode, the environment does not support opening 
  968.     --|   an external file with the given name and form, the exception 
  969.     --|   VLIO_USE_ERROR is raised.
  970.     --|
  971.     --| NA
  972.     --|   MODIFIES
  973.  
  974.  
  975.   procedure CLOSE
  976.             ( File : in out File_Type );
  977.  
  978.     --| OVERVIEW
  979.     --|   This procedure is used to sever the association between the given
  980.     --|   file and its associated external file.  The file is left closed.
  981.     --|
  982.     --| REQUIRES
  983.     --|   The given file must be open.
  984.     --|
  985.     --| EFFECTS
  986.     --|   Association between file name and external file is severed.  
  987.     --|   File is closed.
  988.     --|
  989.     --| RAISES
  990.     --|   VLIO_STATUS_ERROR
  991.     --|
  992.     --| ERRORS
  993.     --|   If the given file is not open, the exception VLIO_STATUS_ERROR is
  994.     --|   raised.
  995.     --|
  996.     --| NA
  997.     --|   MODIFIES
  998.  
  999.  
  1000.   procedure DELETE
  1001.             ( File : in out File_Type );
  1002.  
  1003.     --| OVERVIEW
  1004.     --|   This procedure is similar to the DELETE routine of the DIRECT_IO
  1005.     --|   package and is used to delete the external file associated with
  1006.     --|   the given file.  The given file is closed, and the external file
  1007.     --|   ceases to exist.
  1008.     --|
  1009.     --| REQUIRES
  1010.     --|   The file must be open.
  1011.     --|
  1012.     --| EFFECTS
  1013.     --|   Deletes and closes given file.
  1014.     --|
  1015.     --| RAISES
  1016.     --|   VLIO_STATUS_ERROR, VLIO_USE_ERROR
  1017.     --|
  1018.     --| ERRORS
  1019.     --|   If the given file is not open, the exception VLIO_STATUS_ERROR is
  1020.     --|   raised.  If deletion of the external file is not supported by the
  1021.     --|   environment, the exception VLIO_USE_ERROR is raised.
  1022.     --|
  1023.     --| NA
  1024.     --|   MODIFIES
  1025.  
  1026.  
  1027.   procedure RESET_FILE
  1028.             ( File : in out File_Type );
  1029.  
  1030.     --| OVERVIEW
  1031.     --|   This procedure resets the given file of mode In_Mode so that
  1032.     --|   reading from its elements can be restarted from the beginning of
  1033.     --|   the file;  in particular, for direct access this means that the
  1034.     --|   current index is set to the index of the first record.
  1035.     --|
  1036.     --| REQUIRES
  1037.     --|   The file must be open and must be of mode In_Mode.
  1038.     --|
  1039.     --| EFFECTS
  1040.     --|   Resets file to beginning of file for reading.
  1041.     --|
  1042.     --| RAISES
  1043.     --|   VLIO_STATUS_ERROR, VLIO_MODE_ERROR
  1044.     --|
  1045.     --| ERRORS
  1046.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1047.     --|   If the file is not of mode In_Mode, the exception VLIO_MODE_ERROR
  1048.     --|   is raised.
  1049.     --|
  1050.     --| NA
  1051.     --|   MODIFIES
  1052.  
  1053.  
  1054.  
  1055.   function MODE
  1056.             ( File : in File_Type ) return File_Mode_Type;
  1057.  
  1058.     --| OVERVIEW
  1059.     --|   This procedure is similar to the MODE routine of the DIRECT_IO
  1060.     --|   package and returns the current mode of the given file.
  1061.     --|
  1062.     --| REQUIRES
  1063.     --|   The given file must be open.
  1064.     --|
  1065.     --| EFFECTS
  1066.     --|   Current mode of given file is returned.
  1067.     --|
  1068.     --| RAISES
  1069.     --|   VLIO_STATUS_ERROR
  1070.     --|
  1071.     --| ERRORS
  1072.     --|   If the given file is not open, the exception VLIO_STATUS_ERROR is
  1073.     --|   raised.
  1074.     --|
  1075.     --| NA
  1076.     --|   MODIFIES
  1077.  
  1078.  
  1079.   function NAME
  1080.             ( File : in File_Type ) return string;
  1081.  
  1082.     --| OVERVIEW
  1083.     --|   This procedure is similar to NAME routine of the DIRECT_IO package
  1084.     --|   and returns a string which uniquely identifies the external file
  1085.     --|   currently associated with the given file.
  1086.     --|
  1087.     --| REQUIRES
  1088.     --|   The given file must be open.
  1089.     --|
  1090.     --| EFFECTS
  1091.     --|   String uniquely identifying external file associated with the given
  1092.     --|   file is returned.
  1093.     --|
  1094.     --| RAISES
  1095.     --|   VLIO_STATUS_ERROR
  1096.     --|
  1097.     --| ERRORS
  1098.     --|   If the given file is not open, the eception VLIO_STATUS_ERROR is
  1099.     --|   raised.
  1100.     --|
  1101.     --| NA
  1102.     --|   MODIFIES
  1103.  
  1104.  
  1105.   function FORM
  1106.             ( File : in File_Type ) return string;
  1107.  
  1108.     --| OVERVIEW
  1109.     --|   This procedure is similar to the FORM routine of the DIRECT_IO
  1110.     --|   package and returns the form string for the external file currently
  1111.     --|   associated with the given file.
  1112.     --|
  1113.     --| REQUIRES
  1114.     --|   The given file must be open.
  1115.     --|
  1116.     --| EFFECTS
  1117.     --|   Form string of external file associated with given file is
  1118.     --|   returned.
  1119.     --|
  1120.     --| RAISES
  1121.     --|   VLIO_STATUS_ERROR
  1122.     --|
  1123.     --| ERRORS
  1124.     --|   If the given file is not open, the exception VLIO_STATUS_ERROR is
  1125.     --|   raised.
  1126.     --|
  1127.     --| NA
  1128.     --|   MODIFIES
  1129.  
  1130.  
  1131.   function IS_OPEN
  1132.             ( File : in File_Type ) return boolean;
  1133.  
  1134.     --| OVERVIEW
  1135.     --|   The function IS_OPEN is used similarly to the IS_OPEN routine in the
  1136.     --|   DIRECT_IO package.  It returns TRUE if the given file is open;
  1137.     --|   otherwise it returns FALSE.
  1138.     --|
  1139.     --| NA
  1140.     --|   REQUIRES, EFFECTS, MODIFIES, RAISES, ERRORS
  1141.  
  1142.  
  1143.  
  1144.   procedure READ
  1145.             ( File : in out File_Type;
  1146.               Item : out    Record_Type );
  1147.  
  1148.     --| OVERVIEW
  1149.     --|   This procedure is similar to the sequential Read routine of the
  1150.     --|   DIRECT_IO package.  It operates on a file of any mode and
  1151.     --|   returns in the parameter Item, the value of the element whose
  1152.     --|   position is given by the current read index of the file.  
  1153.     --|   The current read index is advanced.
  1154.     --|
  1155.     --| REQUIRES
  1156.     --|   The given file must be open.  There must be at least one more
  1157.     --|   element to read and that element must be of the Record_Type.
  1158.     --|
  1159.     --| EFFECTS
  1160.     --|   An element of Record_Type is returned in the Item paramenter.
  1161.     --|   The current read index is advanced.
  1162.     --|
  1163.     --| RAISES
  1164.     --|   VLIO_STATUS_ERROR, VLIO_END_ERROR, VLIO_DATA_ERROR
  1165.     --|
  1166.     --| ERRORS
  1167.     --|   If this procedure is called for an unopened file, the exception
  1168.     --|   VLIO_STATUS_ERROR is raised.  
  1169.     --|   If there are no more elements to be read, the exception 
  1170.     --|   VLIO_END_ERROR is raised.  
  1171.     --|   If the element read cannot be interpreted as a value of the 
  1172.     --|   Record_Type, the exception VLIO_DATA_ERROR is raised.
  1173.     --|
  1174.     --| NA
  1175.     --|   MODIFIES
  1176.  
  1177.  
  1178.   procedure READ
  1179.             ( File : in out File_Type;
  1180.               From : in     Internal_File_Pointer_Type;
  1181.               Item : out    Record_Type );
  1182.  
  1183.     --| OVERVIEW
  1184.     --|   This procedure is similar to the direct READ routine of the
  1185.     --|   DIRECT_IO package.  It operates on a file of any mode and sets
  1186.     --|   the current read index of the given file to the index value given by
  1187.     --|   the parameter From.  It returns in the parameter Item, the value
  1188.     --|   of the element whose position is given by the current read index of 
  1189.     --|   the file.  The current read index is advanced.
  1190.     --|
  1191.     --| REQUIRES
  1192.     --|   The given file must be open.  
  1193.     --|   The value of the From parameter must
  1194.     --|   not exceed the size of external file.
  1195.     --|
  1196.     --| EFFECTS
  1197.     --|   The current read index is set to the value of the FROM parameter.  
  1198.     --|   The value at that current read index position is returned in the 
  1199.     --|   Item parameter.  The current read index is advanced.
  1200.     --|
  1201.     --| RAISES
  1202.     --|   VLIO_STATUS_ERROR, VLIO_END_ERROR, VLIO_DATA_ERROR,
  1203.     --|   VLIO_POINTER_ERROR
  1204.     --|
  1205.     --| ERRORS
  1206.     --|   If this procedure is called for an unopened file, the exception
  1207.     --|   VLIO_STATUS_ERROR is raised.  
  1208.     --|   If the element read cannot be interpreted as a value of the 
  1209.     --|   Record_Type, the exception VLIO_DATA_ERROR is raised.  
  1210.     --|   If the index to be used exceeds the size of the external file, 
  1211.     --|   the exception VLIO_END_ERROR is raised.
  1212.     --|   If the From parameter points before the beginning of the file, 
  1213.     --|   the exceptiom VLIO_POINTER_ERROR is raised.
  1214.     --|
  1215.     --| NA
  1216.     --|   MODIFIES
  1217.  
  1218.  
  1219.   procedure WRITE
  1220.             ( File            : in out File_Type;
  1221.               Item : in     Record_Type );
  1222.  
  1223.     --| OVERVIEW
  1224.     --|   This procedure operates on a file of mode Inout_Mode and writes a
  1225.     --|   record of Record_Type to the position in the file denoted by the
  1226.     --|   current write index.  The current write index is advanced.
  1227.     --|
  1228.     --| REQUIRES
  1229.     --|   The given file must be of mode Inout_Mode and must be open.
  1230.     --|                                        
  1231.     --| EFFECTS
  1232.     --|   A record is written to the file at the current write index.  
  1233.     --|   The current write index is advanced.
  1234.     --|
  1235.     --| RAISES
  1236.     --|   VLIO_STATUS_ERROR, VLIO_MODE_ERROR, VLIO_USE_ERROR
  1237.     --|
  1238.     --| ERRORS
  1239.     --|   If the given file is not open, the exception VLIO_STATUS_ERROR is
  1240.     --|   raised.  
  1241.     --|   If the given file is of the mode In_Mode, the exception
  1242.     --|   VLIO_MODE_ERROR is raised.  
  1243.     --|   If the capacity of the external file is exceeded by the write, 
  1244.     --|   the exception VLIO_USE_ERROR is raised.  
  1245.     --|
  1246.     --| NA
  1247.     --|   MODIFIES
  1248.  
  1249.  
  1250.   procedure REWRITE
  1251.             ( File            : in out File_Type;
  1252.               Item : in     Record_Type;
  1253.               To              : in Internal_File_Pointer_Type );
  1254.  
  1255.     --| OVERVIEW
  1256.     --|   This procedure writes a record of Record_Type to
  1257.     --|   the index specified by the To paramenter.
  1258.     --|
  1259.     --| REQUIRES
  1260.     --|   The file must be of mode Inout_Mode and must be open.  
  1261.     --|   A record must exist at the index specified by the To parameter.  
  1262.     --|   The record to be written must be the same length as the record 
  1263.     --|   previously existing at the index specified by the To parameter.
  1264.     --|
  1265.     --| EFFECTS
  1266.     --|   A record is rewritten to the file at the index specified.
  1267.     --|
  1268.     --| RAISES
  1269.     --|   VLIO_STATUS_ERROR, VLIO_MODE_ERROR, VLIO_END_ERROR,
  1270.     --|   VLIO_RECORD_SIZE_ERROR, VLIO_POINTER_ERROR
  1271.     --|
  1272.     --| ERRORS
  1273.     --|   If the given file is not open, 
  1274.     --|   the exception VLIO_STATUS_ERROR is raised.  
  1275.     --|   If the given file is of the mode In_Mode, 
  1276.     --|   the exception VLIO_MODE_ERROR is raised.  
  1277.     --|   If the index to be used exceeds the size of the external file, 
  1278.     --|   the exception VLIO_END_ERROR is raised.
  1279.     --|   If the length of the record to write is not exactly the same 
  1280.     --|   length as the record existing at the index specified, 
  1281.     --|   the exception RECORE_SIZE_ERROR is raised.
  1282.     --|   If the To parameter points to before the beginning of the file, 
  1283.     --|   the exceptiom VLIO_POINTER_ERROR is raised.
  1284.     --|
  1285.     --| NA
  1286.     --|   MODIFIES
  1287.  
  1288.  
  1289.   procedure SET_READ_INDEX
  1290.            ( File : in out File_Type;
  1291.              To   : in     Internal_File_Pointer_Type );
  1292.  
  1293.     --| OVERVIEW
  1294.     --|   This procedure operates on a file of any mode and sets the current
  1295.     --|   read index of the given file to the value of the To parameter.
  1296.     --|
  1297.     --| REQUIRES
  1298.     --|   The given file must be open.
  1299.     --|
  1300.     --| EFFECTS
  1301.     --|   Current read index is set to value of To parameter.
  1302.     --|
  1303.     --| RAISES
  1304.     --|   VLIO_STATUS_ERROR, VLIO_POINTER_ERROR
  1305.     --|
  1306.     --| ERRORS
  1307.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1308.     --|   If the To parameter points before the beginning of the file,
  1309.     --|   the exception VLIO_POINTER_ERROR is raised.
  1310.     --|
  1311.     --| NA
  1312.     --|   MODIFIES
  1313.  
  1314.  
  1315.   procedure SET_WRITE_INDEX
  1316.             ( File : in out File_Type;
  1317.               To   : in     Internal_File_Pointer_Type );
  1318.  
  1319.     --| OVERVIEW
  1320.     --|   This procedure operates on a file of mode Inout_Mode and sets the
  1321.     --|   current write index of the given file to the value of the To 
  1322.     --|   parameter.
  1323.     --|   Records previously written at or after the To parameter will be
  1324.     --|   irretrievable.
  1325.     --|
  1326.     --| REQUIRES
  1327.     --|   The file must be open and must be of mode Inout_Mode.
  1328.     --|
  1329.     --| EFFECTS
  1330.     --|   Current write index is set to value of To parameter.
  1331.     --|
  1332.     --| RAISES
  1333.     --|   VLIO_STATUS_ERROR, VLIO_MODE_ERROR, VLIO_END_ERROR,
  1334.     --|   VLIO_POINTER_ERROR
  1335.     --|
  1336.     --| ERRORS
  1337.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1338.     --|   If the file is of mode In_Mode, the exception VLIO_MODE_ERROR is
  1339.     --|   raised.
  1340.     --|   If the To parameter points beyond the end of the file,
  1341.     --|   the exception VLIO_END_ERROR is raised.
  1342.     --|   If the To parameter points before the beginning of the file,
  1343.     --|   the exception VLIO_POINTER_ERROR is raised.
  1344.     --|
  1345.     --| NA
  1346.     --|   MODIFIES
  1347.  
  1348.  
  1349.   function READ_INDEX
  1350.            ( File : in File_Type ) return Internal_File_Pointer_Type;
  1351.  
  1352.     --| OVERVIEW
  1353.     --|   This procedure operates on a file of any mode and returns the
  1354.     --|   current read index of the given file.
  1355.     --|
  1356.     --| REQUIRES
  1357.     --|   The file must be open.
  1358.     --|
  1359.     --| RAISES
  1360.     --|   VLIO_STATUS_ERROR
  1361.     --|
  1362.     --| ERRORS
  1363.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1364.     --|
  1365.     --| NA
  1366.     --|   EFFECTS, MODIFIES
  1367.  
  1368.  
  1369.   function WRITE_INDEX
  1370.            ( File : in File_Type ) return Internal_File_Pointer_Type;
  1371.  
  1372.     --| OVERVIEW
  1373.     --|   This procedure operates on a file of mode Inout_Mode and returns the
  1374.     --|   current write index of the given file.
  1375.     --|
  1376.     --| REQUIRES
  1377.     --|   The file must be open.
  1378.     --|   The file must be of mode Inout_Mode.
  1379.     --|
  1380.     --| RAISES
  1381.     --|   VLIO_STATUS_ERROR, VLIO_MODE_ERROR
  1382.     --|
  1383.     --| ERRORS
  1384.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1385.     --|   If the file is not of mode Inout_Mode, the exception
  1386.     --|   VLIO_MODE_ERROR is raised.
  1387.     --|
  1388.     --| NA
  1389.     --|   EFFECTS, MODIFIES
  1390.  
  1391.  
  1392.   function SIZE
  1393.            ( File : in File_Type ) return Block_Count_Type;
  1394.  
  1395.     --| OVERVIEW
  1396.     --|   This function operates on a file of any mode and returns the current
  1397.     --|   number of records in the file.  Some of these records may not yet
  1398.     --|   have been written to the external file.
  1399.     --|
  1400.     --| REQUIRES
  1401.     --|   The file must be open.
  1402.     --|
  1403.     --| RAISES
  1404.     --|   VLIO_STATUS_ERROR
  1405.     --|
  1406.     --| ERRORS
  1407.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1408.     --|
  1409.     --| NA
  1410.     --|   EFFECTS, MODIFIES
  1411.  
  1412.  
  1413.   function END_OF_FILE
  1414.            ( File : in File_Type ) return boolean;
  1415.  
  1416.     --| OVERVIEW
  1417.     --|   This function is similar to the END_OF_FILE routine in the DIRECT_IO
  1418.     --|   package.  It operates on a file of any mode and returns TRUE if the
  1419.     --|   current index exceeds the size of the external file; otherwise it
  1420.     --|   returns FALSE.
  1421.     --|
  1422.     --| REQUIRES
  1423.     --|   The file must be open.
  1424.     --|
  1425.     --| RAISES
  1426.     --|   VLIO_STATUS_ERROR
  1427.     --|
  1428.     --| ERRORS
  1429.     --|   If the file is not open, the exception VLIO_STATUS_ERROR is raised.
  1430.     --|
  1431.     --| NA
  1432.     --|   EFFECTS, MODIFIES
  1433.  
  1434.  
  1435.   function NIL return Internal_File_Pointer_Type;
  1436.  
  1437.     --| OVERVIEW
  1438.     --|   This function returns the value nil (or null or nothing) in the
  1439.     --|   form Internal_File_Pointer_Type.
  1440.     --|
  1441.     --| NA
  1442.     --|   REQUIRES, EFFECTS, RAISES, ERRORS, MODIFIES
  1443.  
  1444.  
  1445.   function IS_NIL
  1446.            ( Internal_Ptr : in Internal_File_Pointer_Type ) return boolean;
  1447.  
  1448.     --| OVERVIEW
  1449.     --|   This function returns true if the value of Internal_Ptr is nil;
  1450.     --|   otherwise it returns false.
  1451.     --|
  1452.     --| NA
  1453.     --|   REQUIRES, EFFECTS, RAISES, ERRORS, MODIFIES
  1454.   NAME_ERROR        : exception renames IO_EXCEPTIONS.NAME_ERROR;
  1455.   USE_ERROR         : exception renames IO_EXCEPTIONS.USE_ERROR;
  1456.   STATUS_ERROR      : exception renames IO_EXCEPTIONS.STATUS_ERROR;
  1457.   MODE_ERROR        : exception renames IO_EXCEPTIONS.MODE_ERROR;
  1458.   DEVICE_ERROR      : exception renames IO_EXCEPTIONS.DEVICE_ERROR;
  1459.   END_ERROR         : exception renames IO_EXCEPTIONS.END_ERROR;
  1460.   DATA_ERROR        : exception renames IO_EXCEPTIONS.DATA_ERROR;
  1461.  
  1462.   READ_MODE_ERROR   : exception;
  1463.  
  1464.   VLIO_NAME_ERROR        : exception;
  1465.   VLIO_USE_ERROR         : exception;
  1466.   VLIO_STATUS_ERROR      : exception;
  1467.   VLIO_MODE_ERROR        : exception;
  1468.   VLIO_DEVICE_ERROR      : exception;
  1469.   VLIO_END_ERROR         : exception;
  1470.   VLIO_DATA_ERROR        : exception;
  1471.   VLIO_RECORD_SIZE_ERROR : exception;
  1472.   VLIO_POINTER_ERROR     : exception;
  1473.   VLIO_WRITE_INDEX_ERROR : exception;
  1474.   VLIO_REWRITE_CANT_READ : exception;
  1475.   VLIO_FILE_LIMITS_ERROR : exception;
  1476.   VLIO_INTERNAL_ERROR    : exception;
  1477.   private
  1478.     ---------------------------------------------------------------------------
  1479.     ----                                                                   ----
  1480.     --                  PRIVATE TYPE DECLARATIONS                            --
  1481.     ----                                                                   ----
  1482.     ---------------------------------------------------------------------------
  1483.  
  1484.     subtype Byte_Range_Type is Non_Negative range 0..Bytes_Per_Block;
  1485.  
  1486.     subtype Buffer_Range_Type is Byte_Range_Type range 1..Byte_Range_Type'LAST;
  1487.  
  1488.     subtype Buffer_Type is Record_Type ( Buffer_Range_Type );
  1489.  
  1490.     package VAR_DIRECT_IO is new DIRECT_IO ( Element_Type => Buffer_Type );
  1491.  
  1492.     type Internal_File_Pointer_Type is
  1493.       record
  1494.         Block_Number : VAR_DIRECT_IO.Count;
  1495.         Byte_Offset  : Byte_Range_Type;
  1496.       end record;
  1497.  
  1498.     Start_Of_File : constant Internal_File_Pointer_Type := (1, 1);
  1499.  
  1500.     type File_Type is
  1501.       record
  1502.         File_Identifier    : VAR_DIRECT_IO.File_Type;
  1503.         Is_Open            : Boolean                    := false;
  1504.         Mode               : File_Mode_Type             := Inout_Mode;
  1505.         Buffer             : Buffer_Type;
  1506.         Buffer_Was_Changed : Boolean                    := false;
  1507.         Block_In_Buffer    : VAR_DIRECT_IO.Count        := 0;
  1508.         Read_Index         : Internal_File_Pointer_Type := Start_Of_File;
  1509.         Write_Index        : Internal_File_Pointer_Type := Start_Of_File;
  1510.       end record;
  1511.  
  1512. end VARIABLE_LENGTH_DIRECT_IO;
  1513.  
  1514.  
  1515. -------------------------------------------------------------------------------
  1516. ----                                                                       ----
  1517. --                    VARIABLE LENGTH DIRECT IO PACKAGE BODY                 --
  1518. ----                                                                       ----
  1519. -------------------------------------------------------------------------------
  1520.  
  1521. with UNCHECKED_CONVERSION;
  1522. with MESSAGE_IO;
  1523. use  MESSAGE_IO;
  1524.  
  1525. package body VARIABLE_LENGTH_DIRECT_IO is
  1526. -------------------------------------------------------------------------------
  1527. ----                                                                       ----
  1528. --      TYPES AND CONSTANTS USED ONLY BY VARIABLE_LENGTH_DIRECT_IO BODY      --
  1529. ----                                                                       ----
  1530. -------------------------------------------------------------------------------
  1531.  
  1532.   package MSIO renames MESSAGE_IO;
  1533.  
  1534.   type Process_Type is (Reading, Writing);
  1535.   --| Type to indicate to MOVE_CORRECT_BLOCK INTO BUFFER
  1536.   --| which of these two processes we are doing
  1537.  
  1538.   Non_Negative_Bytes : constant positive := (Non_Negative'SIZE + 7) / 8;
  1539.  
  1540.   subtype VLIO_Non_Negative is Record_Type (1 .. Non_Negative_Bytes);
  1541.  
  1542.   subtype File_Kind_Type is String (1 .. 30);
  1543.  
  1544.   VLIO_File_Flag : constant File_Kind_Type := "Variable Length Direct IO File";
  1545.  
  1546.   type File_Header_Type is
  1547.        record
  1548.          File_Kind : File_Kind_Type := VLIO_File_Flag;
  1549.          Write_Index : Internal_File_Pointer_Type := (0, 0);
  1550.        end record;
  1551.  
  1552.   File_Header_Bytes : constant Integer := (File_Header_Type'SIZE + 7) / 8;
  1553.  
  1554.   subtype VLIO_File_Header_Type is Record_Type (1 .. File_Header_Bytes);
  1555.  
  1556. -------------------------------------------------------------------------------
  1557. ----                                                                       ----
  1558. --          SUBPROGRAMS USED ONLY BY VARIABLE_LENGTH_DIRECT_IO BODY          --
  1559. ----                                                                       ----
  1560. -------------------------------------------------------------------------------
  1561.  
  1562.   --| The two following functions are necessary for translating record lengths
  1563.   --| from an integer subtype to Record_Type and vice-versa
  1564.  
  1565.   function NON_NEGATIVE_TO_VLIO_RECORD is new
  1566.            UNCHECKED_CONVERSION (Source => Non_Negative,
  1567.                                  Target => VLIO_Non_Negative);
  1568.  
  1569.   function VLIO_RECORD_TO_NON_NEGATIVE is new
  1570.            UNCHECKED_CONVERSION (Source => VLIO_Non_Negative,
  1571.                                  Target => Non_Negative);
  1572.  
  1573.  
  1574.   --| The two following functions are necessary for translating record headers
  1575.   --| from Record_Header_Type to Record_Type and vice-versa
  1576.  
  1577.   function FILE_HEADER_TO_VLIO_RECORD is new
  1578.            UNCHECKED_CONVERSION
  1579.            ( Source => File_Header_Type,
  1580.              Target => VLIO_File_Header_Type );
  1581.  
  1582.   function VLIO_RECORD_TO_FILE_HEADER is new
  1583.            UNCHECKED_CONVERSION
  1584.            ( Source => VLIO_File_Header_Type,
  1585.              Target => File_Header_Type );
  1586.  
  1587.  
  1588.   function "<" ( Left  : Internal_File_Pointer_Type;
  1589.                  Right : Internal_File_Pointer_Type ) return BOOLEAN is
  1590.  
  1591.   --| OVERVIEW
  1592.   --|   This function is used to see if one Internal_File_Pointer_Type
  1593.   --|   is less than another.
  1594.   --|
  1595.   --| EFFECTS
  1596.   --|   Returns TRUE if Left is less than Right;
  1597.   --|   returns FALSE otherwise.
  1598.   --|
  1599.   --| NA
  1600.   --|   REQUIRES, RAISES, ERRORS
  1601.   --|
  1602.   --| ALGORITHM
  1603.   --|   If Left is less than Right, then return TRUE;
  1604.   --|   otherwise, return FALSE.
  1605.  
  1606.   Result : Boolean;
  1607.  
  1608.   begin
  1609.     Result := False;
  1610.  
  1611.     if  VAR_DIRECT_IO."<" (Left.Block_Number, Right.Block_Number)  then
  1612.       Result := True;
  1613.     else
  1614.       if  VAR_DIRECT_IO."=" (Left.     Result := True;
  1615.       end if;
  1616.     end if;
  1617.     return Result;
  1618.   end "<";
  1619.  
  1620.  
  1621.   function ">" ( Left  : Internal_File_Pointer_Type;
  1622.                  Right : Internal_File_Pointer_Type ) return BOOLEAN is
  1623.  
  1624.   --| OVERVIEW
  1625.   --|   This function is used to see if one Internal_File_Pointer_Type
  1626.   --|   is greater than another.
  1627.   --|
  1628.   --| EFFECTS
  1629.   --|   Returns TRUE if Left is greater than Right;
  1630.   --|   returns FALSE otherwise.
  1631.   --|
  1632.   --| NA
  1633.   --|   REQUIRES, RAISES, ERRORS
  1634.   --|
  1635.   --| ALGORITHM
  1636.   --|   If Left is greater than Right, then return TRUE;
  1637.   --|   otherwise, return FALSE.
  1638.  
  1639.   Result : Boolean;
  1640.  
  1641.   begin
  1642.     Result := False;
  1643.  
  1644.     if  VAR_DIRECT_IO.">" (Left.Block_Number, Right.Block_Number)  then
  1645.       Result := True;
  1646.     else
  1647.       if  VAR_DIRECT_IO."=" (Left.Block_Number, Right.Block_Number)
  1648.           and then  Left.Byte_Offset > Right.Byte_Offset    then
  1649.         Result := True;
  1650.       end if;
  1651.     end if;
  1652.     return Result;
  1653.   end ">";
  1654.  
  1655.  
  1656.   function ">=" ( Left  : Internal_File_Pointer_Type;
  1657.                   Right : Internal_File_Pointer_Type ) return BOOLEAN is
  1658.  
  1659.   --| OVERVIEW
  1660.   --|   This function is used to see if one Internal_File_Pointer_Type
  1661.   --|   is greater than or equal to another.
  1662.   --|
  1663.   --| EFFECTS
  1664.   --|   Returns TRUE if Left is greater than or equal to Right;
  1665.   --|   returns FALSE otherwise.
  1666.   --|
  1667.   --| NA
  1668.   --|   REQUIRES, RAISES, ERRORS
  1669.   --|
  1670.   --| ALGORITHM
  1671.   --|   If Left is greater than or equal to Right, then return TRUE;
  1672.   --|   otherwise, return FALSE.
  1673.  
  1674.   Result : Boolean;
  1675.  
  1676.   begin
  1677.     Result := False;
  1678.  
  1679.     if  VAR_DIRECT_IO.">" (Left.Block_Number, Right.Block_Number)  then
  1680.       Result := True;
  1681.     else
  1682.       if  VAR_DIRECT_IO."=" (Left.Block_Number, Right.Block_Number)
  1683.           and then  Left.Byte_Offset >= Right.Byte_Offset    then
  1684.         Result := True;
  1685.       end if;
  1686.     end if;
  1687.     return Result;
  1688.   end ">=";
  1689.   procedure MOVE_CORRECT_BLOCK_INTO_BUFFER
  1690.             (File    : in out File_Type;
  1691.              Block   : in     VAR_DIRECT_IO.Positive_Count;
  1692.            Process : in     Process_Type := Reading)  is
  1693.  
  1694.   --| OVERVIEW
  1695.   --|   This procedure insures that the block specified by index into the
  1696.   --|   buffer associated with the given file so that data can be inserted
  1697.   --|   into or extracted from the right block.
  1698.   --|
  1699.   --| REQUIRES
  1700.   --|   The given file must be open.
  1701.   --|   We assume that calling subprograms have checked this condition.
  1702.   --|
  1703.   --| EFFECTS
  1704.   --|   If the specified block is already in the buffer, no action is
  1705.   --|   performed.  Otherwise, the specified block is read from the external
  1706.   --|   file.
  1707.   --|
  1708.   --| RAISES
  1709.   --|   STATUS_ERROR, MODE_ERROR, USE_ERROR, DATA_ERROR, END_ERROR,
  1710.   --|   READ_MODE_ERROR
  1711.   --|
  1712.   --| ERRORS
  1713.   --|   If VAR_DIRECT_IO raises STATUS_ERROR when we try to read (write)
  1714.   --|   from (to) the external file, then STATUS_ERROR is raised.
  1715.   --|   If VAR_DIRECT_IO raises MODE_ERROR when we try to write the current
  1716.   --|   block to the external file, then MODE_ERROR is raised.
  1717.   --|   If VAR_DIRECT_IO raises USE_ERROR when we try to write the current
  1718.   --|   block to the external file, then USE_ERROR is raised.
  1719.   --|   If VAR_DIRECT_IO raises DATA_ERROR when we try to read the specified
  1720.   --|   block from the external file, then DATA_ERROR is raised.
  1721.   --|   If VAR_DIRECT_IO raises END_ERROR when we try to read the specified
  1722.   --|   block from the external file, then END_ERROR is raised.
  1723.   --|   If VAR_DIRECT_IO raises MODE_ERROR when we try to read the specified
  1724.   --|   block from the external file, then READ_MODE_ERROR is raised.
  1725.   --|
  1726.   --| NA
  1727.   --|   MODIFIES
  1728.   --|
  1729.   --| ALGORITHM
  1730.   --|   if the right block is not already in the buffer then
  1731.   --|     if block currently in buffer was modified then
  1732.   --|       write out the buffer to the external file
  1733.   --|     end if
  1734.   --|     read in the right block from the external file
  1735.   --|   end if
  1736.  
  1737.   begin
  1738.     if VAR_DIRECT_IO."/="( Block,  File.Block_In_Buffer )  then
  1739.       if File.Buffer_Was_Changed then                 -- write the changed block
  1740.         begin
  1741.           VAR_DIRECT_IO.WRITE (File => File.File_Identifier,
  1742.                                Item => File.Buffer,
  1743.                                To   => File.Block_In_Buffer);
  1744.         exception
  1745.           when STATUS_ERROR => 
  1746.                MSIO.DISPLAY_MSG ("CMVLIO",
  1747.                                  "STA_MC_A",
  1748.                                  "File not open for write --MOVE BLOCK    ");
  1749.                raise;
  1750.           when MODE_ERROR   => 
  1751.                MSIO.DISPLAY_MSG ("CMVLIO",
  1752.                                  "MOD_MC_A",
  1753.                                  "File wrong mode for write --MOVE BLOCK  ");
  1754.                raise;
  1755.           when USE_ERROR    => 
  1756.                MSIO.DISPLAY_MSG ("CMVLIO",
  1757.                                  "USE_MC_A",
  1758.                                  "Write exceeds file capacity --MOVE BLOCK");
  1759.                raise;
  1760.         end;
  1761.       end if;
  1762.  
  1763.       File.Block_In_Buffer := Block;
  1764.  
  1765.       if  (Process = Reading) or (File.Write_Index.Byte_Offset /= 1)  then
  1766.         begin                                               --read desired block
  1767.           VAR_DIRECT_IO.READ (File => File.File_Identifier,
  1768.                               Item => File.Buffer,
  1769.                               From => Block);
  1770.         exception
  1771.           when STATUS_ERROR => 
  1772.                MSIO.DISPLAY_MSG ("CMVLIO",
  1773.                                  "STA_MC_B",
  1774.                                  "File not open for read --MOVE BLOCK     ");
  1775.                raise;
  1776.           when MODE_ERROR   => 
  1777.                MSIO.DISPLAY_MSG ("CMVLIO",
  1778.                                  "MOD_MC_B",
  1779.                                  "File wrong mode for read --MOVE BLOCK   ");
  1780.                raise READ_MODE_ERROR;
  1781.           when DATA_ERROR   => 
  1782.                MSIO.DISPLAY_MSG ("CMVLIO",
  1783.                                  "DAT_MC_A",
  1784.                                  "Wrong data type on read --MOVE BLOCK    ");
  1785.                raise;
  1786.           when END_ERROR    => 
  1787.                MSIO.DISPLAY_MSG ("CMVLIO",
  1788.                                  "END_MC_A",
  1789.                                  "Read past end-of-file --MOVE BLOCK      ");
  1790.                raise;
  1791.         end;
  1792.       end if;
  1793.  
  1794.     end if;
  1795.   exception
  1796.     when STATUS_ERROR |
  1797.          MODE_ERROR   |
  1798.          USE_ERROR    |
  1799.          DATA_ERROR   |
  1800.          END_ERROR    => raise;              -- avoid "unexpected" message
  1801.     when others       => 
  1802.          MSIO.DISPLAY_MSG ("CMVLIO",
  1803.                            "UNEX_MCA",
  1804.                            "UNEXPECTED ERROR moving block to buffer ");
  1805.          raise;
  1806.   end MOVE_CORRECT_BLOCK_INTO_BUFFER;
  1807.  
  1808.   pragma inline (MOVE_CORRECT_BLOCK_INTO_BUFFER);
  1809.   procedure WRITE_ITEM_INTO_BUFFER
  1810.             (Item : in     Record_Type;
  1811.              File : in out File_Type)  is
  1812.  
  1813.   --| OVERVIEW
  1814.   --|   This procedure is used only by WRITE.  
  1815.   --|   It assumes we are writing at the end of the file.
  1816.   --|   If this procedure were used by REWRITE, 
  1817.   --|   it would destroy data already in the file.
  1818.   --|   This procedure puts the given item into the block-long buffer
  1819.   --|   associated with the file supplied.
  1820.   --|
  1821.   --| REQUIRES
  1822.   --|   The given file must be of mode Inout_Mode and must be open.
  1823.   --|   We assume that calling subprograms have already checked these
  1824.   --|   two conditions.
  1825.   --|
  1826.   --| EFFECTS
  1827.   --|   The given item is put into the buffer associated with the given
  1828.   --|   file.
  1829.   --|   If the current buffer will be filled, it is automatically
  1830.   --|   written to the external file when full and the remainder of the item
  1831.   --|   is then put into a new buffer.
  1832.   --|   The file's Write_Index is updated (points to the byte immediately
  1833.   --|   following the last byte filled by this operation).
  1834.   --|
  1835.   --| RAISES
  1836.   --|   Propogates:
  1837.   --|     STATUS_ERROR, MODE_ERROR, USE_ERROR
  1838.   --|
  1839.   --| ERRORS
  1840.   --|   All error conditions are raised from DIRECT_IO.WRITE
  1841.   --|
  1842.   --| NA
  1843.   --|   MODIFIES
  1844.   --|
  1845.   --| ALGORITHM
  1846.   --|   We make use of Ada's CONSTRAINT_ERROR to implement this algorithm:
  1847.   --|
  1848.   --|     LOOP Forever
  1849.   --|        IF the remaining portion of Item fits into
  1850.   --|                  the available room in the Buffer THEN
  1851.   --|           COPY the remaining portion of Item into
  1852.   --|                  the available room in the Buffer
  1853.   --|           IF Byte_Offset + Item'LENGTH <= Buffer'RANGE'LAST THEN
  1854.   --|              Byte_Offset := Byte_Offset + Item'LENGTH
  1855.   --|              EXIT LOOP
  1856.   --|           ELSE
  1857.   --|              -- Item filled ALL available room in the Buffer
  1858.   --|              INCREMENT Block_Number
  1859.   --|              INITIALIZE Byte_Offset to 1
  1860.   --|              EXIT LOOP
  1861.   --|           END IF
  1862.   --|        ELSE
  1863.   --|           COPY as much of Item as will fit into the Buffer
  1864.   --|           WRITE Buffer out to the external file
  1865.   --|           INCREMENT Block_Number
  1866.   --|           INITIALIZE Byte_Offset to 1
  1867.   --|        END IF
  1868.   --|     END LOOP
  1869.  
  1870.   First : Non_Negative; --index of first char of item yet to be put into buffer
  1871.   Last  : Non_Negative; --index of last char of item yet to be put into buffer
  1872.  
  1873.   Fit : Buffer_Range_Type;   --number of characters that will fit into block
  1874.  
  1875.   begin
  1876.     First := Item'FIRST;
  1877.     Last  := Item'LAST;
  1878.  
  1879.     loop
  1880.       begin
  1881.         -- Try to COPY what remains of Item into Buffer
  1882.         File.Buffer ( File.Write_Index.Byte_Offset ..
  1883.                       File.Write_Index.Byte_Offset + (Last - First + 1) - 1 ) :=
  1884.                Item ( First .. Last );
  1885.  
  1886.         begin
  1887.           -- Try to update Byte_Offset
  1888.           File.Write_Index.Byte_Offset :=
  1889.                File.Write_Index.Byte_Offset + (Last - First + 1);
  1890.  
  1891.         exception
  1892.           when CONSTRAINT_ERROR =>       
  1893.             -- Item ends exactly at end of block
  1894.             -- INCREMENT Block_Number and 
  1895.             -- INITIALIZE Byte_Offset to 1
  1896.             File.Write_Index.Block_Number :=
  1897.                            VAR_DIRECT_IO."+" (File.Write_Index.Block_Number, 1);
  1898.             File.Write_Index.Byte_Offset  := 1;
  1899.         end;
  1900.  
  1901.         File.Buffer_Was_Changed := True;
  1902.         exit;
  1903.  
  1904.       exception
  1905.         when CONSTRAINT_ERROR =>  -- not all of the rest of Item fits into block
  1906.           Fit := (Buffer_Range_Type'LAST - File.Write_Index.Byte_Offset) + 1;
  1907.  
  1908.           -- COPY as much of Item as will fit into Buffer
  1909.           File.Buffer (File.Write_Index.Byte_Offset .. Buffer_Range_Type'LAST)
  1910.               := Item (First .. First + Fit - 1);
  1911.  
  1912.           -- WRITE Buffer out to external file
  1913.           begin
  1914.             VAR_DIRECT_IO.WRITE (File => File.File_Identifier,
  1915.                                  Item => File.Buffer,
  1916.                                  To   => File.Block_In_Buffer);
  1917.           exception
  1918.             when STATUS_ERROR => 
  1919.                  MSIO.DISPLAY_MSG ("CMVLIO",
  1920.                                    "STA_WIB_",
  1921.                                    "File not open for write --WRITE ITEM    ");
  1922.                  raise;
  1923.             when MODE_ERROR   => 
  1924.                  MSIO.DISPLAY_MSG ("CMVLIO",
  1925.                                    "MOD_WIB_",
  1926.                                    "File wrong mode for write --WRITE ITEM  ");
  1927.                  raise;
  1928.             when USE_ERROR    => 
  1929.                  MSIO.DISPLAY_MSG ("CMVLIO",
  1930.                                    "USE_WIB_",
  1931.                                    "Write exceeds file capacity --WRITE ITEM");
  1932.                  raise;
  1933.           end;
  1934.  
  1935.           -- INCREMENT Block_Number and INITIALIZE Byte_Offset to 1
  1936.           File.Write_Index.Block_Number :=
  1937.                            VAR_DIRECT_IO."+" (File.Write_Index.Block_Number, 1);
  1938.           File.Write_Index.Byte_Offset  := 1;
  1939.  
  1940.           File.Buffer := (Buffer_Range_Type => All_False);
  1941.           File.Block_In_Buffer := File.Write_Index.Block_Number;
  1942.  
  1943.           First := First + Fit;
  1944.       end;
  1945.     end loop;
  1946.  
  1947.   exception
  1948.     when STATUS_ERROR |
  1949.          MODE_ERROR   |
  1950.          USE_ERROR    |
  1951.          DATA_ERROR   |
  1952.          END_ERROR    => raise;    -- avoid "unexpected" message
  1953.     when others       => 
  1954.          MSIO.DISPLAY_MSG ("CMVLIO",
  1955.                            "UNEX_WIB",
  1956.                            "UNEXPECTED ERROR writing into buffer    ");
  1957.          raise;
  1958.   end WRITE_ITEM_INTO_BUFFER;
  1959.  
  1960.   pragma inline (WRITE_ITEM_INTO_BUFFER);
  1961.   procedure PUT_ITEM_INTO_BUFFER
  1962.             (Item : in     Record_Type;
  1963.              File : in out File_Type)  is
  1964.  
  1965.   --| OVERVIEW
  1966.   --|   This procedure is used only by REWRITE.
  1967.   --|   It is significantly slower than WRITE_ITEM_INTO_BUFFER
  1968.   --|   and should NOT be called by WRITE (which must execute quickly).
  1969.   --|   This procedure puts the given item into the block-long buffer
  1970.   --|   associated with the file supplied.
  1971.   --|
  1972.   --| REQUIRES
  1973.   --|   The given file must be of mode Inout_Mode and must be open.
  1974.   --|   We assume that calling subprograms have already checked these
  1975.   --|   two conditions.
  1976.   --|
  1977.   --| EFFECTS
  1978.   --|   The given item is put into the buffer associated with the given
  1979.   --|   file.
  1980.   --|   If the current buffer will be filled, it is automatically
  1981.   --|   written to the external file when full and the remainder of the item
  1982.   --|   is then put into a new buffer.
  1983.   --|   The file's Write_Index is updated (points to the byte immediately
  1984.   --|   following the last byte filled by this operation).
  1985.   --|
  1986.   --| RAISES
  1987.   --|   Propogates:
  1988.   --|     STATUS_ERROR, MODE_ERROR, USE_ERROR, DATA_ERROR, END_ERROR,
  1989.   --|     READ_MODE_ERROR
  1990.   --|
  1991.   --| ERRORS
  1992.   --|   All the errors are raised from MOVE_CORRECT_BLOCK_INTO_BUFFER.
  1993.   --|   See that routine for causes of exceptions.
  1994.   --|
  1995.   --| NA
  1996.   --|   MODIFIES
  1997.   --|
  1998.   --| NOTES
  1999.   --|   MODE_ERROR and/or STATUS_ERROR may be raised from lower level.
  2000.   --|
  2001.   --| ALGORITHM
  2002.   --|   We make use of Ada's CONSTRAINT_ERROR to implement this algorithm:
  2003.   --|
  2004.   --|     LOOP Forever
  2005.   --|        IF the remaining portion of Item fits into
  2006.   --|                  th--|           IF Byte_Offset + Item'LENGTH <= Buffer'RANGE'LAST THEN
  2007.   --|              Byte_Offset := Byte_Offset + Item'LENGTH
  2008.   --|              EXIT LOOP
  2009.   --|           ELSE
  2010.   --|              -- Item filled ALL available room in the Buffer
  2011.   --|              INCREMENT Block_Number
  2012.   --|              INITIALIZE Byte_Offset to 1
  2013.   --|              EXIT LOOP
  2014.   --|           END IF
  2015.   --|        ELSE
  2016.   --|           COPY as much of Item as will fit into the Buffer
  2017.   --|           WRITE Buffer out to the external file
  2018.   --|           INCREMENT Block_Number
  2019.   --|           INITIALIZE Byte_Offset to 1
  2020.   --|        END IF
  2021.   --|     END LOOP
  2022.  
  2023.  
  2024.   First : Non_Negative; --index of first char of item yet to be put into buffer
  2025.   Last  : Non_Negative; --index of last char of item yet to be put into buffer
  2026.  
  2027.   Fit : Buffer_Range_Type;   --number of characters that will fit into block
  2028.  
  2029.   begin
  2030.     First := Item'FIRST;
  2031.     Last  := Item'LAST;
  2032.  
  2033.     loop
  2034.       begin
  2035.         -- Try to COPY what remains of Item into Buffer
  2036.         File.Buffer ( File.Write_Index.Byte_Offset ..
  2037.                       File.Write_Index.Byte_Offset + (Last - First + 1) - 1 ) :=
  2038.                Item ( First .. Last );
  2039.  
  2040.         begin
  2041.           -- Try to update Byte_Offset
  2042.           File.Write_Index.Byte_Offset :=
  2043.                File.Write_Index.Byte_Offset + (Last - First + 1);
  2044.  
  2045.         exception
  2046.           when CONSTRAINT_ERROR =>       -- Item ends exactly at end of block
  2047.             -- INCREMENT Block_Number and INITIALIZE Byte_Offset to 1
  2048.             File.Write_Index.Block_Number :=
  2049.                            VAR_DIRECT_IO."+" (File.Write_Index.Block_Number, 1);
  2050.             File.Write_Index.Byte_Offset  := 1;
  2051.         end;
  2052.  
  2053.         File.Buffer_Was_Changed := True;
  2054.         exit;
  2055.  
  2056.       exception
  2057.         when CONSTRAINT_ERROR =>  -- not all of the rest of Item fits into block
  2058.           Fit := (Buffer_Range_Type'LAST - File.Write_Index.Byte_Offset) + 1;
  2059.  
  2060.           -- COPY as much of Item as will fit into Buffer
  2061.           File.Buffer (File.Write_Index.Byte_Offset .. Buffer_Range_Type'LAST)
  2062.               := Item (First .. First + Fit - 1);
  2063.  
  2064.           File.Buffer_Was_Changed := True;
  2065.  
  2066.           -- INCREMENT Block_Number and INITIALIZE Byte_Offset to 1
  2067.           File.Write_Index.Block_Number :=
  2068.                            VAR_DIRECT_IO."+" (File.Write_Index.Block_Number, 1);
  2069.           File.Write_Index.Byte_Offset  := 1;
  2070.  
  2071.           begin
  2072.             -- WRITE Buffer out to external file
  2073.             MOVE_CORRECT_BLOCK_INTO_BUFFER(File, File.Write_Index.Block_Number);
  2074.           exception
  2075.             when END_ERROR => null;         -- do not raise
  2076.                                             -- just means we're writing at EOF
  2077.             when others    => 
  2078.                  MSIO.DISPLAY_MSG ("CMVLIO",
  2079.                                    "MOV_PI_A",
  2080.                                    "Could not move correct block --PUT ITEM ");
  2081.                  raise;
  2082.           end;
  2083.  
  2084.           First := First + Fit;
  2085.       end;
  2086.     end loop;
  2087.  
  2088.   exception
  2089.     when STATUS_ERROR |
  2090.          MODE_ERROR   |
  2091.          USE_ERROR    |
  2092.          DATA_ERROR   |
  2093.          END_ERROR    => raise;    -- avoid "unexpected" message
  2094.     when others       => 
  2095.          MSIO.DISPLAY_MSG ("CMVLIO",
  2096.                            "UNEX_PIA",
  2097.                            "UNEXPECTED ERROR putting into buffer    ");
  2098.          raise;
  2099.   end PUT_ITEM_INTO_BUFFER;
  2100.   procedure GET_ITEM_FROM_BUFFER
  2101.             (File : in out File_Type;
  2102.              Item :    out Record_Type)  is
  2103.  
  2104.   --| OVERVIEW
  2105.   --|   This procedure gets a value for the supplied item out of the
  2106.   --|   block-long buffer associated with the given file.
  2107.   -- open.
  2108.   --|   We assume that calling subprograms have checked this condition.
  2109.   --|
  2110.   --| EFFECTS
  2111.   --|   The value of the given item is extracted from the block-long
  2112.   --|   buffer associated with the given buffer.
  2113.   --|   If the value for the given item overlaps into the next block of
  2114.   --|   the file, that next block is brought into the buffer and the
  2115.   --|   remainder of the given value is extracted from there.
  2116.   --|
  2117.   --| RAISES
  2118.   --|   Propogates:
  2119.   --|     STATUS_ERROR, MODE_ERROR, USE_ERROR, DATA_ERROR, END_ERROR,
  2120.   --|     READ_MODE_ERROR
  2121.   --|
  2122.   --| ERRORS
  2123.   --|   All the errors are raised from MOVE_CORRECT_BLOCK_INTO_BUFFER.
  2124.   --|   See that routine for causes of exceptions.
  2125.   --|
  2126.   --| NA
  2127.   --|   MODIFIES
  2128.   --|
  2129.   --| ALGORITHM
  2130.   --|   We make use of Ada's CONSTRAINT_ERROR to implement this algorithm:
  2131.   --|
  2132.   --|     LOOP Forever
  2133.   --|        IF the remaining portion of the desired Item is in the Buffer THEN
  2134.   --|           COPY the remaining portion of Item from the Buffer
  2135.   --|           IF Byte_Offset + Item'LENGTH <= Buffer'RANGE'LAST  THEN
  2136.   --|              Byte_Offset := Byte_Offset + Item'LENGTH
  2137.   --|              EXIT LOOP
  2138.   --|           ELSE
  2139.   --|              -- Item ended exactly at the end of the Buffer
  2140.   --|              INCREMENT Block_Number
  2141.   --|              INITIALIZE Byte_Offset to 1
  2142.   --|              EXIT LOOP
  2143.   --|           END IF
  2144.   --|        ELSE
  2145.   --|           COPY as much of Item as is in the Buffer
  2146.   --|           READ next block into Buffer from the external file
  2147.   --|           INCREMENT Block_Number
  2148.   --|           INITIALIZE Byte_Offset to 1
  2149.   --|        END IF
  2150.   --|     END LOOP
  2151.  
  2152.   First : Non_Negative; --index of first char of item yet to be got from buffer
  2153.   Last  : Non_Negative; --index of last char of item yet to be got from buffer
  2154.  
  2155.   Available : Buffer_Range_Type; --number of characters that will fit into block
  2156.  
  2157.   begin
  2158.     First := Item'FIRST;
  2159.     Last  := Item'LAST;
  2160.  
  2161.     loop
  2162.       begin
  2163.         -- Try to copy remainder of Item from Buffer
  2164.         Item (First .. Last) :=
  2165.         File.Buffer ( File.Read_Index.Byte_Offset ..
  2166.                       File.Read_Index.Byte_Offset + (Last - First + 1) - 1 );
  2167.  
  2168.         begin
  2169.           -- Try to update Byte_Offset
  2170.           File.Read_Index.Byte_Offset :=
  2171.                File.Read_Index.Byte_Offset + (Last - First + 1);
  2172.  
  2173.         exception
  2174.           when CONSTRAINT_ERROR =>       -- Item ends exactly at end of block
  2175.             -- INCREMENT Block_Number and INITIALIZE Byte_Offset to 1
  2176.             File.Read_Index.Block_Number :=
  2177.                             VAR_DIRECT_IO."+" (File.Read_Index.Block_Number, 1);
  2178.             File.Read_Index.Byte_Offset  := 1;
  2179.         end;
  2180.  
  2181.         exit;
  2182.  
  2183.       exception
  2184.         when CONSTRAINT_ERROR =>  -- not all of the rest of Item is in block
  2185.           Available :=
  2186.                     (Buffer_Range_Type'LAST - File.Read_Index.Byte_Offset) + 1;
  2187.  
  2188.           -- COPY as much of Item as is in Buffer
  2189.           Item (First .. First + Available - 1) :=
  2190.           File.Buffer (File.Read_Index.Byte_Offset .. Buffer_Range_Type'LAST);
  2191.  
  2192.           -- INCREMENT Block_Number and INITIALIZE Byte_Offset to 1
  2193.           File.Read_Index.Block_Number :=
  2194.                           VAR_DIRECT_IO."+" (File.Read_Index.Block_Number, 1);
  2195.           File.Read_Index.Byte_Offset  := 1;
  2196.  
  2197.           begin
  2198.             -- READ next block in from external file
  2199.             MOVE_CORRECT_BLOCK_INTO_BUFFER (File, File.Read_Index.Block_Number);
  2200.           exception
  2201.             when END_ERROR => 
  2202.                  MSIO.DISPLAY_MSG ("CMVLIO",
  2203.                                    "END_GI_A",
  2204.                                    "Read past end-of-file --GET ITEM        ");
  2205.                  raise;
  2206.             when others    => 
  2207.                  MSIO.DISPLAY_MSG ("CMVLIO",
  2208.                                    "MOV_GI_A",
  2209.                                    "Could not move correct block --GET ITEM ");
  2210.                  raise;
  2211.           end;
  2212.  
  2213.           First := Buffer_Range_Type(First) + Available;
  2214.       end;
  2215.     end loop;
  2216.  
  2217.   exception
  2218.     when STATUS_ERROR |
  2219.          MODE_ERROR   |
  2220.          USE_ERROR    |
  2221.          DATA_ERROR   |
  2222.          END_ERROR    => raise;      -- avoid "unexpected" message
  2223.     when others       => 
  2224.          MSIO.DISPLAY_MSG ("CMVLIO",
  2225.                            "UNEX_GIA",
  2226.                            "UNEXPECTED ERROR getting from buffer    ");
  2227.          raise;
  2228.   end GET_ITEM_FROM_BUFFER;
  2229. ---------------------------------------------------------------------------
  2230. ----                                                                   ----
  2231. --                         PACKAGE ENTRY POINTS                          --
  2232. ----                                                                   ----
  2233. ---------------------------------------------------------------------------
  2234.  
  2235.  
  2236.   procedure CREATE
  2237.             ( File : in out File_Type;
  2238.               Mode : in     File_Mode_Type := Inout_Mode;
  2239.               Name : in     string := "";
  2240.               Form : in     string := "" )  is
  2241.  
  2242.   --| OVERVIEW
  2243.   --|   This procedure is similar the CREATE routine of the DIRECT_IO
  2244.   --|   package and is used to establish a new external file, with the
  2245.   --|   given name, mode and form, and to associate this external file 
  2246.   --|   with the given file.  The given file is left open.  The default
  2247.   --|   access mode is Inout_Mode.
  2248.   --|
  2249.   --| ALGORITHM
  2250.   --|   Use procedure of same name from DIRECT_IO.
  2251.  
  2252.   File_Header : File_Header_Type;
  2253.  
  2254.   Converted_Mode : VAR_DIRECT_IO.File_Mode;
  2255.  
  2256.   begin
  2257.     if mode = In_Mode then
  2258.       Converted_Mode := VAR_DIRECT_IO.In_File;
  2259.       File.Write_Index := NIL;
  2260.     else
  2261.       Converted_Mode := VAR_DIRECT_IO.Inout_File;
  2262.     end if;
  2263.  
  2264.     begin
  2265.       VAR_DIRECT_IO.CREATE ( File => File.File_Identifier,
  2266.                              Mode => Converted_Mode,
  2267.                              Name => Name,
  2268.                              Form => Form );
  2269.     exception
  2270.       when STATUS_ERROR => 
  2271.            MSIO.DISPLAY_MSG ("CMVLIO",
  2272.                              "STA_CR_A",
  2273.                              "File already open when trying to CREATE ");
  2274.            raise VLIO_STATUS_ERROR;
  2275.       when NAME_ERROR   => 
  2276.            MSIO.DISPLAY_MSG ("CMVLIO",
  2277.                              "NAM_CR_B",
  2278.                              "Illegal Name specified on CREATE        ");
  2279.            raise VLIO_NAME_ERROR;
  2280.       when USE_ERROR    => 
  2281.            MSIO.DISPLAY_MSG ("CMVLIO",
  2282.                              "USE_CR_B",
  2283.                              "Illegal Mode or Form specified on CREATE");
  2284.            raise VLIO_USE_ERROR;
  2285.     end;
  2286.  
  2287.     File.Is_Open := True;
  2288.     File.Mode    := Mode;
  2289.  
  2290.     if  Mode = Inout_Mode  then
  2291.       File_Header := ( File_Kind   => VLIO_File_Flag,
  2292.                        Write_Index => (0, 0) );
  2293.  
  2294.       begin
  2295.         WRITE                   -- write file header
  2296.         ( File => File,                    -- end index will be updated at close
  2297.           Item => FILE_HEADER_TO_VLIO_RECORD (File_Header) );
  2298.       exception
  2299.         when others => 
  2300.              MSIO.DISPLAY_MSG ("CMVLIO",
  2301.                                "WR_CR_FH",
  2302.                                "Error writing File Header during CREATE ");
  2303.              raise;
  2304.       end;
  2305.     end if;
  2306.  
  2307.   exception
  2308.     when VLIO_USE_ERROR |
  2309.          VLIO_NAME_ERROR |
  2310.          VLIO_STATUS_ERROR => raise;     -- avoid "unexpected" message
  2311.     when others            => 
  2312.          MSIO.DISPLAY_MSG ("CMVLIO",
  2313.                            "UNEX_CRA",
  2314.                            "UNEXPECTED ERROR when trying to CREATE  ");
  2315.          raise;
  2316.   end CREATE;
  2317.  
  2318.  
  2319.  
  2320.   procedure OPEN
  2321.             ( File : in out File_Type;
  2322.               Mode : in   File_Mode_Type;
  2323.               Name : in   string;
  2324.               Form : in   string := "" )  is
  2325.  
  2326.   --| OVERVIEW
  2327.   --|   This procedure is used similarly to the open routine in the
  2328.   --|   DIRECT_IO package.  The given file is associated with an existing
  2329.   --|   external file having the given name and form, and sets the current
  2330.   --|   mode of the given file to the given mode.  The given file is left
  2331.   --|   open and the current read index and write index are set to the 
  2332.   --|   index of the first user record.  
  2333.   --|
  2334.   --| ALGORITHM
  2335.   --|   Use procedure of same name from DIRECT_IO.
  2336.   --|   READ the Write_Index (End-Of-File pointer) from the file.
  2337.  
  2338.   File_Header : VLIO_File_Header_Type;
  2339.  
  2340.   Converted_Mode : VAR_DIRECT_IO.File_Mode;
  2341.  
  2342.   begin
  2343.     if mode = In_Mode then
  2344.       Converted_Mode := VAR_DIRECT_IO.In_File;
  2345.     else
  2346.       Converted_Mode := VAR_DIRECT_IO.Inout_File;
  2347.     end if;
  2348.  
  2349.     begin
  2350.       VAR_DIRECT_IO.Open ( File => File.File_Identifier,
  2351.                            Mode => Converted_Mode,
  2352.                            Name => Name,
  2353.                            Form => Form );
  2354.     exception
  2355.       when STATUS_ERROR => 
  2356.            MSIO.DISPLAY_MSG ("CMVLIO",
  2357.                              "STA_OP_A",
  2358.                              "File already open when trying to OPEN   ");
  2359.            raise VLIO_STATUS_ERROR;
  2360.       when NAME_ERROR   => 
  2361.            MSIO.DISPLAY_MSG ("CMVLIO",
  2362.                              "NAM_OP_B",
  2363.                              "Illegal Name specified on OPEN          ");
  2364.            raise VLIO_NAME_ERROR;
  2365.       when USE_ERROR    => 
  2366.            MSIO.DISPLAY_MSG ("CMVLIO",
  2367.                              "USE_OP_B",
  2368.                              "Illegal Mode or Form specified on OPEN  ");
  2369.            raise VLIO_USE_ERROR;
  2370.     end;
  2371.  
  2372.     File.Is_Open := True;
  2373.     File.Mode    := Mode;
  2374.  
  2375.     --  Find the end-of-file index;  It is part of the File_Header.
  2376.     --  First, set Write Index to its highest possible value so that
  2377.     --  we don't "read past end-of-file" when searching for the real
  2378.     --  Write Index (end-of-file indicator).
  2379.     File.Write_Index.Block_Number := VAR_DIRECT_IO.Count'LAST;
  2380.     File.Write_Index.Byte_Offset  := Byte_Range_Type'LAST;
  2381.     begin
  2382.       READ ( File => File,
  2383.                         Item => File_Header,
  2384.                         From => Start_Of_File );
  2385.       File.Write_Index := VLIO_RECORD_TO_FILE_HEADER( File_Header ).Write_Index;
  2386.     exception
  2387.       when others => 
  2388.            MSIO.DISPLAY_MSG ("CMVLIO",
  2389.                              "RD_OP_FH",
  2390.                              "Error reading File Header during OPEN   ");
  2391.            raise;
  2392.     end;
  2393.   exception
  2394.     when VLIO_USE_ERROR |
  2395.          VLIO_NAME_ERROR |
  2396.          VLIO_STATUS_ERROR => raise;    -- avoid "unexpected" message
  2397.     when others            => 
  2398.          MSIO.DISPLAY_MSG ("CMVLIO",
  2399.                            "UNEX_OPA",
  2400.                            "UNEXPECTED ERROR on OPEN attempt        ");
  2401.          raise;
  2402.   end OPEN;
  2403.  
  2404.  
  2405.  
  2406.   procedure CLOSE ( File : in out File_Type )  is
  2407.  
  2408.   --| OVERVIEW
  2409.   --|   This procedure is used to sever the association between the given
  2410.   --|   file and its associated external file.  The file is left closed.
  2411.   --|
  2412.   --| ALGORITHM
  2413.   --|   Update the Write_Index (End-Of-File pointer) on file if necessary.
  2414.   --|   Use procedure of same name from DIRECT_IO.
  2415.  
  2416.   File_Header : File_Header_Type;
  2417.  
  2418.   begin
  2419.     if  File.Mode = Inout_Mode  then
  2420.       -- Update the end-of-file index;
  2421.       -- It is part of the File_Header
  2422.       begin
  2423.         File_Header := (VLIO_File_Flag,  File.Write_Index);
  2424.         REWRITE ( File,                  -- update EOF index
  2425.                              FILE_HEADER_TO_VLIO_RECORD ( File_Header ),
  2426.                              Start_Of_File );
  2427.       exception
  2428.         when others => 
  2429.              MSIO.DISPLAY_MSG ("CMVLIO",
  2430.                                "RW_CL_FH",
  2431.                                "Error rewriting File Header during CLOSE");
  2432.              raise;
  2433.       end;
  2434.  
  2435.       begin
  2436.         VAR_DIRECT_IO.WRITE ( File.File_Identifier,   -- flush the buffer
  2437.                               File.Buffer,            -- (first block of file)
  2438.                               1 );
  2439.       exception
  2440.         when STATUS_ERROR => 
  2441.              MSIO.DISPLAY_MSG ("CMVLIO",
  2442.                                "STA_FL__",
  2443.                                "File not open to Flush during CLOSE     ");    
  2444.              raise VLIO_STATUS_ERROR;
  2445.         when MODE_ERROR   => 
  2446.              MSIO.DISPLAY_MSG ("CMVLIO",
  2447.                                "MOD_FL__",
  2448.                                "File wrong mode to Flush during CLOSE   ");
  2449.              raise;
  2450.         when USE_ERROR    => 
  2451.              MSIO.DISPLAY_MSG ("CMVLIO",
  2452.                                "USE_FL__",
  2453.                                "Flush excedes file capacity during CLOSE");
  2454.              raise;
  2455.       end;
  2456.     end if;
  2457.  
  2458.     begin
  2459.       VAR_DIRECT_IO.CLOSE ( File => File.File_Identifier );  -- close the file
  2460.     exception
  2461.       when STATUS_ERROR => 
  2462.            MSIO.DISPLAY_MSG ("CMVLIO",
  2463.                              "STA_CL_A",
  2464.                              "File not open when trying to CLOSE      ");
  2465.            raise VLIO_STATUS_ERROR;
  2466.     end;
  2467.  
  2468.     File.Is_Open := False;
  2469.  
  2470.   exception
  2471.     when VLIO_STATUS_ERROR => raise;     -- avoid "unexpected" message
  2472.     when others            => 
  2473.          MSIO.DISPLAY_MSG ("CMVLIO",
  2474.                            "UNEX_CLA",
  2475.                            "UNEXPECTED ERROR when trying to CLOSE   ");
  2476.          raise;
  2477.   end CLOSE;
  2478.  
  2479.  
  2480.  
  2481.   procedure DELETE ( File : in out File_Type )  is
  2482.  
  2483.   --| OVERVIEW
  2484.   --|   This procedure is similar to the DELETE routine of the DIRECT_IO
  2485.   --|   package and is used to delete the external file associated with
  2486.   --|   the given file.  The given file is closed, and the external file
  2487.   --|   ceases to exist.
  2488.   --|
  2489.   --| ALGORITHM
  2490.   --|   Use procedure of same name from DIRECT_IO.
  2491.  
  2492.   begin
  2493.     VAR_DIRECT_IO.DELETE ( File => File.File_Identifier );
  2494.     File.Is_Open := False;
  2495.   exception
  2496.     when STATUS_ERROR => 
  2497.          MSIO.DISPLAY_MSG ("CMVLIO",
  2498.                            "STA_DE_A",
  2499.                            "File not open when trying to DELETE     ");
  2500.          raise VLIO_STATUS_ERROR;
  2501.     when USE_ERROR    => 
  2502.          MSIO.DISPLAY_MSG ("CMVLIO",
  2503.                            "USE_DE_A",
  2504.                            "Action not allowed when trying to DELETE");
  2505.          raise VLIO_USE_ERROR;
  2506.     when others       => 
  2507.          MSIO.DISPLAY_MSG ("CMVLIO",
  2508.                            "UNEX_DEA",
  2509.                            "UNEXPECTED ERROR when trying to DELETE  ");
  2510.          raise;
  2511.   end DELETE;
  2512.  
  2513.  
  2514.  
  2515.   procedure RESET_FILE ( File : in out File_Type )  is
  2516.  
  2517.   --| OVERVIEW
  2518.   --|   This procedure resets the given file of any mode so that
  2519.   --|   reading from its elements can be restarted from the beginning of
  2520.   --|   the file;  in particular, for direct access this means that the
  2521.   --|   current index is set to the index of the first user record.
  2522.   --|
  2523.   --| ALGORITHM
  2524.   --|   Read File Header to set read index to first user record.
  2525.  
  2526.   File_Header : VLIO_File_Header_Type;
  2527.  
  2528.   begin
  2529.     begin
  2530.       READ ( File => File,
  2531.                         Item => File_Header,
  2532.                         From => Start_Of_File );
  2533.     exception
  2534.       when VLIO_STATUS_ERROR => 
  2535.            MSIO.DISPLAY_MSG ("CMVLIO",
  2536.                              "STA_RS_A",
  2537.                              "File not open when trying to RESET      ");
  2538.            raise;
  2539.       when others            => 
  2540.            MSIO.DISPLAY_MSG ("CMVLIO",
  2541.                              "UNEX_RSA",
  2542.                              "UNEXPECTED ERROR when trying to RESET   ");
  2543.            raise;
  2544.     end;
  2545.   end RESET_FILE;
  2546.  
  2547.  
  2548.  
  2549.   function MODE ( File : in File_Type ) return File_Mode_Type  is
  2550.  
  2551.   --| OVERVIEW
  2552.   --|   This procedure is similar to the MODE routine of the DIRECT_IO
  2553.   --|   package and returns the current mode of the given file.
  2554.   --|
  2555.   --| ALGORITHM
  2556.   --|   Use function of same name from DIRECT_IO.
  2557.  
  2558.   Mode_Of_File : VAR_DIRECT_IO.File_Mode;
  2559.  
  2560.   begin
  2561.     return File.Mode;
  2562.   exception
  2563.     when others            => 
  2564.          MSIO.DISPLAY_MSG ("CMVLIO",
  2565.                            "UNEX_MOA",
  2566.                            "UNEXPECTED ERROR when finding MODE      ");
  2567.          raise;
  2568.   end MODE;
  2569.  
  2570.  
  2571.  
  2572.   function NAME ( File : in File_Type ) return string  is
  2573.  
  2574.   --| OVERVIEW
  2575.   --|   This procedure is similar to NAME routine of the DIRECT_IO package
  2576.   --|   and returns a string which uniquely identifies the external file
  2577.   --|   currently associated with the given file.
  2578.   --|
  2579.   --| ALGORITHM
  2580.   --|   Use function of same name from DIRECT_IO.
  2581.  
  2582.   begin
  2583.     return VAR_DIRECT_IO.Name ( File => File.File_Identifier );
  2584.   exception
  2585.     when STATUS_ERROR => 
  2586.          MSIO.DISPLAY_MSG ("CMVLIO",
  2587.                            "STA_NA_A",
  2588.                            "File not open when finding NAME         ");
  2589.          raise VLIO_STATUS_ERROR;
  2590.     when others       => 
  2591.          MSIO.DISPLAY_MSG ("CMVLIO",
  2592.                            "UNEX_NAA",
  2593.                            "UNEXPECTED ERROR when finding NAME      ");
  2594.          raise;
  2595.   end NAME;
  2596.  
  2597.  
  2598.  
  2599.   function FORM ( File : in File_Type ) return string  is
  2600.  
  2601.   --| OVERVIEW
  2602.   --|   This procedure is similar to the FORM routine of the DIRECT_IO
  2603.   --|   package and returns the form string for the external file currently
  2604.   --|   associated with the given file.
  2605.   --|
  2606.   --| ALGORITHM
  2607.   --|   Use function of same name from DIRECT_IO.
  2608.  
  2609.   begin
  2610.     return VAR_DIRECT_IO.FORM ( File => File.File_Identifier );
  2611.   exception
  2612.     when STATUS_ERROR => 
  2613.          MSIO.DISPLAY_MSG ("CMVLIO",
  2614.                            "STA_FO_A",
  2615.                            "File not open when finding FORM         ");
  2616.          raise VLIO_STATUS_ERROR;
  2617.     when others       => 
  2618.          MSIO.DISPLAY_MSG ("CMVLIO",
  2619.                            "UNEX_FOA",
  2620.                            "UNEXPECTED ERROR when finding FORM      ");
  2621.          raise;
  2622.   end FORM;
  2623.  
  2624.  
  2625.  
  2626.   function IS_OPEN ( File : in File_Type ) return boolean  is
  2627.  
  2628.   --| OVERVIEW
  2629.   --|   The function IS_OPEN is used similarly to the IS_OPEN routine in the
  2630.   --|   DIRECT_IO package.  It returns TRUE if the given file is open;
  2631.   --|   otherwise it returns FALSE.
  2632.   --|
  2633.   --| ALGORITHM
  2634.   --|   Use function of same name from DIRECT_IO.
  2635.  
  2636.   begin
  2637.     return File.Is_Open;
  2638.   exception
  2639.     when others => 
  2640.          MSIO.DISPLAY_MSG ("CMVLIO",
  2641.                            "UNEX_IOA",
  2642.                            "UNEXPECTED ERROR when checking IS_OPEN  ");
  2643.          raise;
  2644.   end IS_OPEN;
  2645.  
  2646.  
  2647.  
  2648.   procedure READ
  2649.             ( File : in out File_Type;
  2650.               Item : out  Record_Type )  is
  2651.  
  2652.   --| OVERVIEW
  2653.   --|   This procedure is similar to the sequential Read routine of the
  2654.   --|   DIRECT_IO package.  It operates on a file of any mode and
  2655.   --|   returns in the parameter Item, the value of the element whose
  2656.   --|   position is given by the current index of the file.  
  2657.   --|   The current read index is increased by one.
  2658.   --|
  2659.   --| ALGORITH
  2660.   --|   Check open.
  2661.   --|   Get correct block into buffer.
  2662.   --|   Get length of next record from buffer and compare to Item'LENGTH.
  2663.   --|   Get the item from the buffer.
  2664.  
  2665.   Record_Length : VLIO_Non_Negative;
  2666.  
  2667.   begin
  2668.     if not File.Is_Open then
  2669.       MSIO.DISPLAY_MSG ("CMVLIO",
  2670.                         "STA_RD_A",
  2671.                         "File not open when trying to READ       ");
  2672.       raise STATUS_ERROR;
  2673.     end if;
  2674.  
  2675.     if  File.Read_Index >= File.Write_Index  then
  2676.       MSIO.DISPLAY_MSG ("CMVLIO",
  2677.                         "END_RD_A",
  2678.                         "Past end-of-file when beginning READ    ");
  2679.       raise END_ERROR;
  2680.     end if;
  2681.  
  2682.     begin
  2683.       MOVE_CORRECT_BLOCK_INTO_BUFFER( File  => File,
  2684.                                       Block => File.Read_Index.Block_Number );
  2685.     exception
  2686.       when others => 
  2687.            MSIO.DISPLAY_MSG ("CMVLIO",
  2688.                              "MOV_RD_A",
  2689.                              "Error moving block when beginning READ  ");
  2690.            raise;
  2691.     end;
  2692.  
  2693.     begin
  2694.       GET_ITEM_FROM_BUFFER ( File => File,
  2695.                              Item => Record_Length );
  2696.     exception
  2697.       when others => 
  2698.            MSIO.DISPLAY_MSG ("CMVLIO",
  2699.                              "GET_RD_A",
  2700.                              "Error getting item when beginning READ  ");
  2701.            raise;
  2702.     end;
  2703.  
  2704.     if VLIO_RECORD_TO_NON_NEGATIVE (Record_Length) = Item'LENGTH then
  2705.       begin
  2706.         MOVE_CORRECT_BLOCK_INTO_BUFFER( File  => File,
  2707.                                         Block => File.Read_Index.Block_Number );
  2708.       exception
  2709.         when others => 
  2710.              MSIO.DISPLAY_MSG ("CMVLIO",
  2711.                                "MOV_RD_B",
  2712.                                "Error moving block when finishing READ  ");
  2713.              raise;
  2714.       end;
  2715.  
  2716.       begin
  2717.         GET_ITEM_FROM_BUFFER ( File => File,
  2718.                                Item => Item );
  2719.       exception
  2720.         when others => 
  2721.              MSIO.DISPLAY_MSG ("CMVLIO",
  2722.                                "GET_RD_B",
  2723.                                "Error getting item when finishing READ  ");
  2724.              raise;
  2725.       end;
  2726.     else
  2727.       MSIO.DISPLAY_MSG ("CMVLIO",
  2728.                         "DAT_RD_A",
  2729.                         "Record on file wrong size during READ   ");
  2730.       raise DATA_ERROR;
  2731.     end if;
  2732.  
  2733.     if  File.Read_Index > File.Write_Index  then
  2734.       MSIO.DISPLAY_MSG ("CMVLIO",
  2735.                         "END_RD_B",
  2736.                         "Past end-of-file when finishing READ    ");
  2737.       raise END_ERROR;
  2738.     end if;
  2739.  
  2740.   exception
  2741.     when STATUS_ERROR => raise VLIO_STATUS_ERROR;
  2742.     when DATA_ERROR   => raise VLIO_DATA_ERROR;
  2743.     when END_ERROR    => raise VLIO_END_ERROR;
  2744.     when others       => 
  2745.          MSIO.DISPLAY_MSG ("CMVLIO",
  2746.                            "UNEX__RD",
  2747.                            "UNEXPECTED ERROR READing record         ");
  2748.          raise;
  2749.   end READ;
  2750.  
  2751.  
  2752.  
  2753.   procedure READ
  2754.             ( File : in out File_Type;
  2755.               From : in   Internal_File_Pointer_Type;
  2756.               Item : out  Record_Type )  is
  2757.  
  2758.   --| OVERVIEW
  2759.   --|   This procedure is similar to the direct READ routine of the
  2760.   --|   DIRECT_IO package.  It operates on a file of any mode and sets
  2761.   --|   the current read index of the given file to the index value given by
  2762.   --|   the parameter From.  It returns in the parameter Item, the value
  2763.   --|   of the element whose position is given by the current read index of the
  2764.   --|   file.  The current read index is advanced.
  2765.   --|
  2766.   --| ALGORITHM
  2767.   --|   Check From.
  2768.   --|   Set read index.
  2769.   --|   Call READ.
  2770.  
  2771.   begin
  2772.     if not File.Is_Open then
  2773.       MSIO.DISPLAY_MSG ("CMVLIO",
  2774.                         "STA_RF_A",
  2775.                         "File not open when trying to Direct-READ");
  2776.       raise VLIO_STATUS_ERROR;
  2777.     end if;
  2778.  
  2779.     if  VAR_DIRECT_IO."<" (From.Block_Number, 1)  then
  2780.       MSIO.DISPLAY_MSG ("CMVLIO",
  2781.                         "POI_RF_A",
  2782.                         "Direct-READ from before start-of-file   ");
  2783.       raise VLIO_POINTER_ERROR;
  2784.     end if;
  2785.  
  2786.     File.Read_Index := From;
  2787.  
  2788.     begin
  2789.       READ ( File => File,
  2790.              Item => Item );
  2791.     exception
  2792.       when others => 
  2793.            MSIO.DISPLAY_MSG ("CMVLIO",
  2794.                              "RD_RF_A_",
  2795.                              "Read Error when trying to Direct-READ   ");
  2796.            raise;
  2797.     end;
  2798.   exception
  2799.     when VLIO_END_ERROR     |
  2800.          VLIO_DATA_ERROR    |
  2801.          VLIO_STATUS_ERROR  |
  2802.          VLIO_POINTER_ERROR => raise;
  2803.     when END_ERROR          => raise VLIO_END_ERROR;
  2804.     when others             => 
  2805.          MSIO.DISPLAY_MSG ("CMVLIO",
  2806.                            "UNEX_RDF",
  2807.                            "UNEXPECTED ERROR Direct-READing record  ");
  2808.          raise;
  2809.   end READ;
  2810.  
  2811.  
  2812.  
  2813.   procedure WRITE
  2814.             ( File : in out File_Type;
  2815.               Item : in     Record_Type )  is
  2816.  
  2817.   --| OVERVIEW
  2818.   --|   This procedure operates on a file of mode Inout_Mode and writes a
  2819.   --|   record of Record_Type to the position in the file denoted by the
  2820.   --|   current write index.  The current write index is advanced.
  2821.   --|
  2822.   --| ALGORITHM
  2823.   --|   Check open and Mode.
  2824.   --|   Get correct block into the buffer.
  2825.   --|   Put the item into the buffer.
  2826.  
  2827.   begin
  2828.     if not File.Is_Open then
  2829.       MSIO.DISPLAY_MSG ("CMVLIO",
  2830.                         "STA_WR_A",
  2831.                         "File not open when trying to WRITE      ");
  2832.       raise VLIO_STATUS_ERROR;
  2833.     end if;
  2834.  
  2835.     if File.Mode /= Inout_Mode then
  2836.       MSIO.DISPLAY_MSG ("CMVLIO",
  2837.                         "MOD_WR_A",
  2838.                         "File wrong mode when trying to WRITE    ");
  2839.       raise VLIO_MODE_ERROR;
  2840.     end if;
  2841.  
  2842.     begin
  2843.       MOVE_CORRECT_BLOCK_INTO_BUFFER (File    => File,
  2844.                                       Block   => File.Write_Index.Block_Number,
  2845.                                       Process => Writing);
  2846.     exception
  2847.       when others => 
  2848.            MSIO.DISPLAY_MSG ("CMVLIO",
  2849.                              "MOV_WR_A",
  2850.                              "Error moving block into buffer --WRITE  ");
  2851.            raise;
  2852.     end;
  2853.  
  2854.     begin
  2855.       WRITE_ITEM_INTO_BUFFER
  2856.           ( File => File,
  2857.             Item => ( NON_NEGATIVE_TO_VLIO_RECORD( Item'LENGTH ) & Item )
  2858.           );
  2859.     exception
  2860.       when others => 
  2861.            MSIO.DISPLAY_MSG ("CMVLIO",
  2862.                              "WRI_WR_A",
  2863.                              "Error writing item into buffer --WRITE  ");
  2864.            raise;
  2865.     end;
  2866.  
  2867.   exception
  2868.     when STATUS_ERROR | VLIO_STATUS_ERROR => 
  2869.          raise VLIO_STATUS_ERROR;
  2870.     when MODE_ERROR | VLIO_MODE_ERROR => 
  2871.          raise VLIO_MODE_ERROR;
  2872.     when USE_ERROR | VLIO_USE_ERROR => 
  2873.          raise VLIO_USE_ERROR;
  2874.     when others            => 
  2875.          MSIO.DISPLAY_MSG ("CMVLIO",
  2876.                            "UNEX_WRA",
  2877.                            "UNEXPECTED ERROR WRITing record         ");
  2878.          raise;
  2879.   end WRITE;
  2880.  
  2881.  
  2882.   procedure REWRITE
  2883.             ( File : in out File_Type;
  2884.               Item : in     Record_Type;
  2885.               To   : in     Internal_File_Pointer_Type )  is
  2886.  
  2887.   --| OVERVIEW
  2888.   --|   This procedure writes a record of Record_Type to
  2889.   --|   the index specified by the To paramenter.
  2890.   --|
  2891.   --| ALGORITHM
  2892.   --|   Check open, Mode, and To.
  2893.   --|   Save indexes.
  2894.   --|   Get the item at specified place and compare lengths of items.
  2895.   --|   Put the given item into the buffer.
  2896.   --|   Restore the indexes.
  2897.   --|
  2898.   --| NOTES
  2899.   --|   REWRITE'ing to the end of the file is NOT allowed!
  2900.  
  2901.   Temp_Read_Index  : Internal_File_Pointer_Type;
  2902.   Temp_Write_Index : Internal_File_Pointer_Type;
  2903.  
  2904.   Record_Length : VLIO_Non_Negative;
  2905.  
  2906.   begin
  2907.     if not File.Is_Open then
  2908.       MSIO.DISPLAY_MSG ("CMVLIO",
  2909.                         "STA_RW_A",
  2910.                         "File not open when trying to REWRITE    ");
  2911.       raise VLIO_STATUS_ERROR;
  2912.     end if;
  2913.  
  2914.     if File.Mode /= Inout_Mode then
  2915.       MSIO.DISPLAY_MSG ("CMVLIO",
  2916.                         "MOD_RW_A",
  2917.                         "File wrong mode when trying to REWRITE  ");
  2918.       raise VLIO_MODE_ERROR;
  2919.     end if;
  2920.  
  2921.     if  To < Start_Of_File  then
  2922.       MSIO.DISPLAY_MSG ("CMVLIO",
  2923.                         "POI_RW_A",
  2924.                         "Cannot REWRITE before start-of-file     ");
  2925.       raise VLIO_POINTER_ERROR;
  2926.     end if;
  2927.  
  2928.     if To >= File.Write_Index then
  2929.       MSIO.DISPLAY_MSG ("CMVLIO",
  2930.                         "END_RW_A",
  2931.                         "Cannot REWRITE past end-of-file         ");
  2932.       raise VLIO_END_ERROR;
  2933.     end if;
  2934.  
  2935.     Temp_Read_Index  := File.Read_Index;
  2936.     Temp_Write_Index := File.Write_Index;
  2937.     File.Read_Index  := To;
  2938.  
  2939.     begin
  2940.       MOVE_CORRECT_BLOCK_INTO_BUFFER (File  => File,
  2941.                                       Block => File.Read_Index.Block_Number);
  2942.     exception
  2943.       when END_ERROR => null;
  2944.       when others    => 
  2945.            MSIO.DISPLAY_MSG ("CMVLIO",
  2946.                              "MOV_RW_A",
  2947.                              "Error moving block --beginning REWRITE  ");
  2948.            raise;
  2949.     end;
  2950.  
  2951.     begin
  2952.       GET_ITEM_FROM_BUFFER ( File => File,
  2953.                              Item => Record_Length );
  2954.     exception
  2955.       when others => 
  2956.            MSIO.DISPLAY_MSG ("CMVLIO",
  2957.                              "GET_RW_A",
  2958.                              "Error getting item --beginning REWRITE  ");
  2959.            raise;
  2960.     end;
  2961.  
  2962.     if VLIO_RECORD_TO_NON_NEGATIVE (Record_Length) = Item'LENGTH then
  2963.       File.Write_Index := File.Read_Index;
  2964.  
  2965.       begin
  2966.         MOVE_CORRECT_BLOCK_INTO_BUFFER (File  => File,
  2967.                                         Block => File.Write_Index.Block_Number);
  2968.       exception
  2969.         when END_ERROR => null;
  2970.         when others    => 
  2971.              MSIO.DISPLAY_MSG ("CMVLIO",
  2972.                                "MOV_RW_B",
  2973.                                "Error moving block --finishing REWRITE  ");
  2974.              raise;
  2975.       end;
  2976.  
  2977.       begin
  2978.         PUT_ITEM_INTO_BUFFER ( File => File,
  2979.                                Item => Item );
  2980.       exception
  2981.         when others => 
  2982.              MSIO.DISPLAY_MSG ("CMVLIO",
  2983.                                "PUT_RW_A",
  2984.                                "Error putting item --finishing REWRITE  ");
  2985.              raise;
  2986.       end;
  2987.  
  2988.     else
  2989.       MSIO.DISPLAY_MSG ("CMVLIO",
  2990.                         "SIZ_RW_A",
  2991.                         "Record on file wrong size during REWRITE");
  2992.       raise VLIO_RECORD_SIZE_ERROR;
  2993.     end if;
  2994.  
  2995.     File.Read_Index  := Temp_Read_Index;
  2996.     File.Write_Index := Temp_Write_Index;
  2997.   exception
  2998.     when STATUS_ERROR | VLIO_STATUS_ERROR => 
  2999.          raise VLIO_STATUS_ERROR;
  3000.     when MODE_ERROR | VLIO_MODE_ERROR => 
  3001.          raise VLIO_MODE_ERROR;
  3002.     when END_ERROR | VLIO_END_ERROR => 
  3003.          raise VLIO_END_ERROR;
  3004.     when USE_ERROR | VLIO_USE_ERROR => 
  3005.          raise VLIO_USE_ERROR;
  3006.     when VLIO_POINTER_ERROR | VLIO_RECORD_SIZE_ERROR => 
  3007.          raise;
  3008.     when others => 
  3009.          MSIO.DISPLAY_MSG ("CMVLIO",
  3010.                            "UNEX_RWE",
  3011.                            "UNEXPECTED ERROR REWRITing record       ");
  3012.          raise;
  3013.   end REWRITE;
  3014.  
  3015.  
  3016.   procedure SET_READ_INDEX
  3017.             ( File : in out File_Type;
  3018.               To   : in     Internal_File_Pointer_Type )  is
  3019.  
  3020.   --| OVERVIEW
  3021.   --|   This procedure operates on a file any mode and sets the current
  3022.   --|   read index of the given file to the value of the To parameter.
  3023.   --|
  3024.   --| ALGORITHM
  3025.   --|   Check open and To
  3026.   --|   Set read index = To.
  3027.  
  3028.   begin
  3029.     if not File.Is_Open then
  3030.       MSIO.DISPLAY_MSG ("CMVLIO",
  3031.                         "STA_SR_A",
  3032.                         "File not open to SET READ INDEX         ");
  3033.       raise VLIO_STATUS_ERROR;
  3034.     end if;
  3035.  
  3036.     if  To < Start_Of_File  then
  3037.       MSIO.DISPLAY_MSG ("CMVLIO",
  3038.                         "POI_SR_A",
  3039.                         "SETting READ INDEX before start-of-file ");
  3040.       raise VLIO_POINTER_ERROR;
  3041.     else
  3042.       File.Read_Index := To;
  3043.     end if;
  3044.  
  3045.   exception
  3046.     when VLIO_STATUS_ERROR | VLIO_POINTER_ERROR => 
  3047.          raise;
  3048.     when others => 
  3049.          MSIO.DISPLAY_MSG ("CMVLIO",
  3050.                            "UNEX_SRA",
  3051.                            "UNEXPECTED ERROR SETting READ INDEX     ");
  3052.          raise;
  3053.   end SET_READ_INDEX;
  3054.  
  3055.  
  3056.  
  3057.   procedure SET_WRITE_INDEX
  3058.             ( File : in out File_Type;
  3059.               To   : in     Internal_File_Pointer_Type )  is
  3060.  
  3061.   --| OVERVIEW
  3062.   --|   This procedure operates on a file of mode Inout_Mode and sets the
  3063.   --|   current write index of the given file to the value of the To parameter.
  3064.   --|   Records previously written at or after the To parameter will be
  3065.   --|   irretrievable.
  3066.   --|
  3067.   --| ALGORITHM
  3068.   --|   Check open and mode.
  3069.   --|   Set write index = To.
  3070.   --|   Clear the rest of the file
  3071.  
  3072.   begin
  3073.     if not File.Is_Open then
  3074.       MSIO.DISPLAY_MSG ("CMVLIO",
  3075.                         "STA_SW_A",
  3076.                         "File not open to SET WRITE INDEX        ");
  3077.       raise VLIO_STATUS_ERROR;
  3078.     end if;
  3079.  
  3080.     if File.Mode /= Inout_Mode then
  3081.       MSIO.DISPLAY_MSG ("CMVLIO",
  3082.                         "MOD_SW_A",
  3083.                         "File wrong mode to  SET WRITE INDEX     ");
  3084.       raise VLIO_MODE_ERROR;
  3085.     end if;
  3086.  
  3087.     if  To < Start_Of_File  then
  3088.       MSIO.DISPLAY_MSG ("CMVLIO",
  3089.                         "POI_SW_A",
  3090.                         "SETting WRITE INDEX before start-of-file");
  3091.       raise VLIO_POINTER_ERROR;
  3092.     end if;
  3093.  
  3094.     if To > File.Write_Index then
  3095.       MSIO.DISPLAY_MSG ("CMVLIO",
  3096.                         "END_SW_A",
  3097.                         "SETting WRITE INDEX after end-of-file   ");
  3098.       raise VLIO_END_ERROR;
  3099.     end if;
  3100.  
  3101.     File.Write_Index := To;
  3102.  
  3103.   exception
  3104.     when VLIO_STATUS_ERROR |
  3105.          VLIO_MODE_ERROR   |
  3106.          VLIO_END_ERROR    |
  3107.          VLIO_POINTER_ERROR => raise;
  3108.     when others             => 
  3109.          MSIO.DISPLAY_MSG ("CMVLIO",
  3110.                            "UNEX_SWA",
  3111.                            "UNEXPECTED ERROR SETting WRITE INDEX    ");
  3112.          raise;
  3113.   end SET_WRITE_INDEX;
  3114.  
  3115.  
  3116.  
  3117.   function READ_INDEX
  3118.            ( File : in File_Type ) return Internal_File_Pointer_Type  is
  3119.  
  3120.   --| OVERVIEW
  3121.   --|   This procedure operates on a file of any mode and returns the
  3122.   --|   current read index of the given file.
  3123.   --|
  3124.   --| ALGORITHM
  3125.   --|   Check open.
  3126.   --|   Return the value of the file's read index.
  3127.  
  3128.   begin
  3129.     if not File.Is_Open then
  3130.       MSIO.DISPLAY_MSG ("CMVLIO",
  3131.                         "STA_RI_A",
  3132.                         "File not open when finding READ INDEX   ");
  3133.       raise VLIO_STATUS_ERROR;
  3134.     end if;
  3135.  
  3136.     return File.Read_Index;
  3137.   exception
  3138.     when VLIO_STATUS_ERROR => raise;
  3139.     when others            => 
  3140.          MSIO.DISPLAY_MSG ("CMVLIO",
  3141.                            "UNEX_RIA",
  3142.                            "UNEXPECTED ERROR finding READ INDEX     ");
  3143.          raise;
  3144.   end READ_INDEX;
  3145.  
  3146.  
  3147.  
  3148.   function WRITE_INDEX
  3149.            ( File : in File_Type ) return Internal_File_Pointer_Type  is
  3150.  
  3151.   --| OVERVIEW
  3152.   --|   This procedure operates on a file of Inout mode and returns the
  3153.   --|   current write index of the given file.
  3154.   --|
  3155.   --| ALGORITHM
  3156.   --|   Check open and mode.
  3157.   --|   Return the value of the file's write index.
  3158.  
  3159.   begin
  3160.     if not File.Is_Open then
  3161.       MSIO.DISPLAY_MSG ("CMVLIO",
  3162.                         "STA_WI_A",
  3163.                         "File not open when finding WRITE INDEX  ");
  3164.       raise VLIO_STATUS_ERROR;
  3165.     end if;
  3166.  
  3167.     if File.Mode /= Inout_Mode then
  3168.       MSIO.DISPLAY_MSG ("CMVLIO",
  3169.                         "MOD_WI_A",
  3170.                         "File wrong mode when finding WRITE INDEX");
  3171.       raise VLIO_MODE_ERROR;
  3172.     end if;
  3173.  
  3174.     return File.Write_Index;
  3175.   exception
  3176.     when VLIO_STATUS_ERROR |
  3177.          VLIO_MODE_ERROR   => raise;
  3178.     when others            => 
  3179.          MSIO.DISPLAY_MSG ("CMVLIO",
  3180.                            "UNEX_WIA",
  3181.                            "UNEXPECTED ERROR finding WRITE INDEX    ");
  3182.          raise;
  3183.   end WRITE_INDEX;
  3184.  
  3185.  
  3186.  
  3187.   function SIZE ( File : in File_Type ) return Block_Count_Type  is
  3188.  
  3189.   --| OVERVIEW
  3190.   --|   This function operates on a file of any mode and returns the current
  3191.   --|   number of bytes in the file.  Some of those bytes may not yet have
  3192.   --|   been written to the external file.
  3193.   --|
  3194.   --| ALGORITHM
  3195.   --|   Check open.
  3196.   --|   Return number of bytes in file.
  3197.  
  3198.   begin
  3199.     if not File.Is_Open then
  3200.       MSIO.DISPLAY_MSG ("CMVLIO",
  3201.                         "STA_SZ_A",
  3202.                         "File not open when finding SIZE         ");
  3203.       raise VLIO_STATUS_ERROR;
  3204.     else
  3205.       return Block_Count_Type (
  3206.   ((Integer(File.Write_Index.Block_Number) - 1) * Integer(Byte_Range_Type'LAST))
  3207.   + Integer(File.Write_Index.Byte_Offset)  - 1
  3208.                         );
  3209.     end if;
  3210.   exception
  3211.     when VLIO_STATUS_ERROR => raise;
  3212.     when others            => 
  3213.          MSIO.DISPLAY_MSG ("CMVLIO",
  3214.                            "UNEX_SZA",
  3215.                            "UNEXPECTED ERROR finding SIZE           ");
  3216.          raise;
  3217.   end SIZE;
  3218.  
  3219.  
  3220.  
  3221.   function END_OF_FILE ( File : in File_Type ) return boolean  is
  3222.  
  3223.   --| OVERVIEW
  3224.   --|   This function is similar to the END_OF_FILE routine in the DIRECT_IO
  3225.   --|   package.  It operates on a file of any mode and returns TRUE if the
  3226.   --|   current read index exceeds the size of the external file;
  3227.   --|   otherwise it returns FALSE.
  3228.   --|
  3229.   --| ALGORITHM
  3230.   --|   If read index is greater than end index then return true
  3231.   --|   else return false
  3232.  
  3233.   begin
  3234.     if not File.Is_Open then
  3235.       MSIO.DISPLAY_MSG ("CMVLIO",
  3236.                         "STA_EO_A",
  3237.                         "File not open when checking END-OF-FILE ");
  3238.       raise VLIO_STATUS_ERROR;
  3239.     end if;
  3240.  
  3241.     if File.Read_Index >= File.Write_Index then
  3242.       return True;
  3243.     else
  3244.       return False;
  3245.     end if;
  3246.   exception
  3247.     when VLIO_STATUS_ERROR => raise;
  3248.     when others            => 
  3249.          MSIO.DISPLAY_MSG ("CMVLIO",
  3250.                            "UNEX_EOF",
  3251.                            "UNEXPECTED ERROR checking END-OF-FILE   ");
  3252.          raise;
  3253.   end END_OF_FILE;
  3254.  
  3255.  
  3256.  
  3257.   function NIL return Internal_File_Pointer_Type  is
  3258.  
  3259.   --| OVERVIEW
  3260.   --|   This function returns the value nil (or null or nothing) in the
  3261.   --|   form Internal_File_Pointer_Type.
  3262.   --|
  3263.   --| ALGORITHM
  3264.   --|   NIL = Internal_File_Pointer_Type'( Block_Number => 0,
  3265.   --|                                      Byte_Offset  => 0 );
  3266.  
  3267.   begin
  3268.     return Internal_File_Pointer_Type'( Block_Number => 0,
  3269.                                         Byte_Offset  => 0 );
  3270.   end NIL;
  3271.  
  3272.  
  3273.  
  3274.   function IS_NIL
  3275.            ( Internal_Ptr : in Internal_File_Pointer_Type ) return boolean  is
  3276.  
  3277.   --|  OVERVIEW
  3278.   --|    This function returns true if the value of Internal_Ptr is nil;
  3279.   --|    otherwise it returns false.
  3280.   --|
  3281.   --|  ALGORITHM
  3282.   --|    TRUE iff Internal_ptr = NIL
  3283.  
  3284.   Result : Boolean;
  3285.  
  3286.   begin
  3287.     Result := False;
  3288.  
  3289.     if  Internal_Ptr = Internal_File_Pointer_Type'(0, 0)  then
  3290.       Result := True;
  3291.     end if;
  3292.  
  3293.     return Result;
  3294.   end IS_NIL;
  3295.  
  3296.  
  3297. end VARIABLE_LENGTH_DIRECT_IO;
  3298.