-- $Date: 2004/02/14 09:59:14 $
-- $Revision: 1.18 $
-- $Author: jcrocholl $

with Readers; use Readers;
with Token_Readers; use Token_Readers;
with String_Lists; use String_Lists;

-- Light-weight XML input file readers.
package XML_Readers is

   -- Light-weight XML input file reader.
   type XML_Reader is
     new Token_Reader with
      record
         Contexts : String_List_Access;
      end record;

   -- Type for instance variables.
   type XML_Reader_Access is access XML_Reader;

   -------------------------------------------
   -- Internal initialization and finalization
   -------------------------------------------

   -- These don't need to be called directly because the functions
   -- Current_Input, Open and Close will do it for you.

   -- Initialize a newly created reader instance.
   procedure Initialize_XML_Reader
     (This : access XML_Reader'Class);

   -- Initialize a newly created reader instance with a file to read.
   procedure Initialize_XML_Reader
     (This     : access XML_Reader'Class;
      Filename : in String); -- Open this file for reading.

   -- Close the input file.
   procedure Finalize_XML_Reader
     (This : access XML_Reader'Class); -- Object instance.

   -------------------
   -- Creating readers
   -------------------

   -- Create an XML reader for current input (stdin).
   function Current_Input
     return XML_Reader_Access-- The newly created XML reader instance.

   -- Create an XML reader for file input.
   function Open
     (Filename : in String)    -- Open this file.
     return XML_Reader_Access-- The newly created XML reader instance.

   -- Close an XML reader's input file.
   procedure Close
     (This : in out XML_Reader_Access); -- Close this XML reader.

   --------------
   -- End testing
   --------------

   -- Check if the end of the tag has been reached.
   function End_Of_Tag
     (This : access XML_Reader'Class)
     return Boolean-- End of tag?

   -----------------
   -- Error handling
   -----------------

   -- Print an error message, then raise Syntax_Error.
   procedure XML_Expect_Error
     (This    : access XML_Reader'Class;
      Final   : in String;  -- This text was expected...
      Choices : in String); -- ... or one of these.

   -----------
   -- Contexts
   -----------

   -- Get the innermost context.
   function Get_Context
     (This : access XML_Reader'Class-- Get context from this reader.
     return String;                        -- The current context value.

   -- Check the innermost context.
   function Context_Is
     (This    : access XML_Reader'Class-- Get context from this reader.
      Context : in String)                    -- The current context value.
     return Boolean;                          -- True if the context is as specified.

   ---------------
   -- Reading tags
   ---------------

   -- Expect '<' first. Then read one word.
   -- If it starts with '/', pop context and return false.
   -- Otherwise push context and return true.
   function Descend
     (This : access XML_Reader'Class)
     return Boolean-- True if a new context level was started.

   -- Read the next tag name. Check if it is what we expect.
   -- Call Error if not, and that raises Syntax_Error.
   procedure Assert_Tag_Name
     (This : access XML_Reader'Class;
      Name : in String); -- Expect this tag name.

   -- Skip over closing '>' (and possibly '/' or '?').
   procedure Exit_Tag
     (This : access XML_Reader'Class);

   -- Assert the next tag name, then exit tag and return.
   procedure Assert_Tag
     (This : access XML_Reader'Class;
      Name : in String); -- Expect this tag name.

   -- Leave the innermost element: skip over closing tag that matches
   -- the element name stored in This.Context.
   procedure Exit_Element
     (This : access XML_Reader'Class);

   ---------------------
   -- Reading attributes
   ---------------------

   -- Read one token.
   procedure Read_Attribute_Name
     (This : access XML_Reader'Class);

   -- Read the next attribute name. Check if it is what we expect.
   -- Call Error if not, and that raises Syntax_Error.
   procedure Assert_Attribute_Name
     (This : access XML_Reader'Class;
      Name : in String); -- Expect this attribute name.

   -- Expect '=' first, then read one token.
   procedure Read_Attribute_Value
     (This : access XML_Reader'Class);

   -- Read the next attribute value. Check if it is what we expect.
   -- Call Error if not, and that raises Syntax_Error.
   procedure Assert_Attribute_Value
     (This  : access XML_Reader'Class;
      Value : in String); -- Expect this attribute value.

   ---------------
   -- Reading data
   ---------------

   -- Read characters from input until '<' is found.
   function Read_Data
     (This : access XML_Reader'Class)
     return String-- The data that was read.

   -- Read characters enclosed with an element.
   function Read_Element_Data
     (This : access XML_Reader'Class;
      Name : in String-- Assert starting and closing tag.
     return String;     -- The data that was read.

end XML_Readers;