OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [g-cgi.adb] - Rev 801

Go to most recent revision | Compare with Previous | Blame | View Log

------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                             G N A T . C G I                              --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                      Copyright (C) 2001-2010, AdaCore                    --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------
 
with Ada.Text_IO;
with Ada.Strings.Fixed;
with Ada.Characters.Handling;
with Ada.Strings.Maps;
 
with GNAT.OS_Lib;
with GNAT.Table;
 
package body GNAT.CGI is
 
   use Ada;
 
   Valid_Environment : Boolean := True;
   --  This boolean will be set to False if the initialization was not
   --  completed correctly. It must be set to true there because the
   --  Initialize routine (called during elaboration) will use some of the
   --  services exported by this unit.
 
   Current_Method : Method_Type;
   --  This is the current method used to pass CGI parameters
 
   Header_Sent : Boolean := False;
   --  Will be set to True when the header will be sent
 
   --  Key/Value table declaration
 
   type String_Access is access String;
 
   type Key_Value is record
      Key   : String_Access;
      Value : String_Access;
   end record;
 
   package Key_Value_Table is new Table (Key_Value, Positive, 1, 1, 50);
 
   -----------------------
   -- Local subprograms --
   -----------------------
 
   procedure Check_Environment;
   pragma Inline (Check_Environment);
   --  This procedure will raise Data_Error if Valid_Environment is False
 
   procedure Initialize;
   --  Initialize CGI package by reading the runtime environment. This
   --  procedure is called during elaboration. All exceptions raised during
   --  this procedure are deferred.
 
   --------------------
   -- Argument_Count --
   --------------------
 
   function Argument_Count return Natural is
   begin
      Check_Environment;
      return Key_Value_Table.Last;
   end Argument_Count;
 
   -----------------------
   -- Check_Environment --
   -----------------------
 
   procedure Check_Environment is
   begin
      if not Valid_Environment then
         raise Data_Error;
      end if;
   end Check_Environment;
 
   ------------
   -- Decode --
   ------------
 
   function Decode (S : String) return String is
      Result : String (S'Range);
      K      : Positive := S'First;
      J      : Positive := Result'First;
 
   begin
      while K <= S'Last loop
         if K + 2 <= S'Last
           and then  S (K) = '%'
           and then Characters.Handling.Is_Hexadecimal_Digit (S (K + 1))
           and then Characters.Handling.Is_Hexadecimal_Digit (S (K + 2))
         then
            --  Here we have '%HH' which is an encoded character where 'HH' is
            --  the character number in hexadecimal.
 
            Result (J) := Character'Val
              (Natural'Value ("16#" & S (K + 1 .. K + 2) & '#'));
            K := K + 3;
 
         --  Plus sign is decoded as a space
 
         elsif S (K) = '+' then
            Result (J) := ' ';
            K := K + 1;
 
         else
            Result (J) := S (K);
            K := K + 1;
         end if;
 
         J := J + 1;
      end loop;
 
      return Result (Result'First .. J - 1);
   end Decode;
 
   -------------------------
   -- For_Every_Parameter --
   -------------------------
 
   procedure For_Every_Parameter is
      Quit : Boolean;
 
   begin
      Check_Environment;
 
      for K in 1 .. Key_Value_Table.Last loop
 
         Quit := False;
 
         Action (Key_Value_Table.Table (K).Key.all,
                 Key_Value_Table.Table (K).Value.all,
                 K,
                 Quit);
 
         exit when Quit;
 
      end loop;
   end For_Every_Parameter;
 
   ----------------
   -- Initialize --
   ----------------
 
   procedure Initialize is
 
      Request_Method : constant String :=
                         Characters.Handling.To_Upper
                           (Metavariable (CGI.Request_Method));
 
      procedure Initialize_GET;
      --  Read CGI parameters for a GET method. In this case the parameters
      --  are passed into QUERY_STRING environment variable.
 
      procedure Initialize_POST;
      --  Read CGI parameters for a POST method. In this case the parameters
      --  are passed with the standard input. The total number of characters
      --  for the data is passed in CONTENT_LENGTH environment variable.
 
      procedure Set_Parameter_Table (Data : String);
      --  Parse the parameter data and set the parameter table
 
      --------------------
      -- Initialize_GET --
      --------------------
 
      procedure Initialize_GET is
         Data : constant String := Metavariable (Query_String);
      begin
         Current_Method := Get;
 
         if Data /= "" then
            Set_Parameter_Table (Data);
         end if;
      end Initialize_GET;
 
      ---------------------
      -- Initialize_POST --
      ---------------------
 
      procedure Initialize_POST is
         Content_Length : constant Natural :=
                            Natural'Value (Metavariable (CGI.Content_Length));
         Data : String (1 .. Content_Length);
 
      begin
         Current_Method := Post;
 
         if Content_Length /= 0 then
            Text_IO.Get (Data);
            Set_Parameter_Table (Data);
         end if;
      end Initialize_POST;
 
      -------------------------
      -- Set_Parameter_Table --
      -------------------------
 
      procedure Set_Parameter_Table (Data : String) is
 
         procedure Add_Parameter (K : Positive; P : String);
         --  Add a single parameter into the table at index K. The parameter
         --  format is "key=value".
 
         Count : constant Positive :=
                   1 + Strings.Fixed.Count (Data, Strings.Maps.To_Set ("&"));
         --  Count is the number of parameters in the string. Parameters are
         --  separated by ampersand character.
 
         Index : Positive := Data'First;
         Amp   : Natural;
 
         -------------------
         -- Add_Parameter --
         -------------------
 
         procedure Add_Parameter (K : Positive; P : String) is
            Equal : constant Natural := Strings.Fixed.Index (P, "=");
 
         begin
            if Equal = 0 then
               raise Data_Error;
 
            else
               Key_Value_Table.Table (K) :=
                 Key_Value'(new String'(Decode (P (P'First .. Equal - 1))),
                            new String'(Decode (P (Equal + 1 .. P'Last))));
            end if;
         end Add_Parameter;
 
      --  Start of processing for Set_Parameter_Table
 
      begin
         Key_Value_Table.Set_Last (Count);
 
         for K in 1 .. Count - 1 loop
            Amp := Strings.Fixed.Index (Data (Index .. Data'Last), "&");
 
            Add_Parameter (K, Data (Index .. Amp - 1));
 
            Index := Amp + 1;
         end loop;
 
         --  add last parameter
 
         Add_Parameter (Count, Data (Index .. Data'Last));
      end Set_Parameter_Table;
 
   --  Start of processing for Initialize
 
   begin
      if Request_Method = "GET" then
         Initialize_GET;
 
      elsif Request_Method = "POST" then
         Initialize_POST;
 
      else
         Valid_Environment := False;
      end if;
 
   exception
      when others =>
 
         --  If we have an exception during initialization of this unit we
         --  just declare it invalid.
 
         Valid_Environment := False;
   end Initialize;
 
   ---------
   -- Key --
   ---------
 
   function Key (Position : Positive) return String is
   begin
      Check_Environment;
 
      if Position <= Key_Value_Table.Last then
         return Key_Value_Table.Table (Position).Key.all;
      else
         raise Parameter_Not_Found;
      end if;
   end Key;
 
   ----------------
   -- Key_Exists --
   ----------------
 
   function Key_Exists (Key : String) return Boolean is
   begin
      Check_Environment;
 
      for K in 1 .. Key_Value_Table.Last loop
         if Key_Value_Table.Table (K).Key.all = Key then
            return True;
         end if;
      end loop;
 
      return False;
   end Key_Exists;
 
   ------------------
   -- Metavariable --
   ------------------
 
   function Metavariable
     (Name     : Metavariable_Name;
      Required : Boolean := False) return String
   is
      function Get_Environment (Variable_Name : String) return String;
      --  Returns the environment variable content
 
      ---------------------
      -- Get_Environment --
      ---------------------
 
      function Get_Environment (Variable_Name : String) return String is
         Value  : OS_Lib.String_Access := OS_Lib.Getenv (Variable_Name);
         Result : constant String := Value.all;
      begin
         OS_Lib.Free (Value);
         return Result;
      end Get_Environment;
 
      Result : constant String :=
                 Get_Environment (Metavariable_Name'Image (Name));
 
   --  Start of processing for Metavariable
 
   begin
      Check_Environment;
 
      if Result = "" and then Required then
         raise Parameter_Not_Found;
      else
         return Result;
      end if;
   end Metavariable;
 
   -------------------------
   -- Metavariable_Exists --
   -------------------------
 
   function Metavariable_Exists (Name : Metavariable_Name) return Boolean is
   begin
      Check_Environment;
 
      if Metavariable (Name) = "" then
         return False;
      else
         return True;
      end if;
   end Metavariable_Exists;
 
   ------------
   -- Method --
   ------------
 
   function Method return Method_Type is
   begin
      Check_Environment;
      return Current_Method;
   end Method;
 
   --------
   -- Ok --
   --------
 
   function Ok return Boolean is
   begin
      return Valid_Environment;
   end Ok;
 
   ----------------
   -- Put_Header --
   ----------------
 
   procedure Put_Header
     (Header : String  := Default_Header;
      Force  : Boolean := False)
   is
   begin
      if Header_Sent = False or else Force then
         Check_Environment;
         Text_IO.Put_Line (Header);
         Text_IO.New_Line;
         Header_Sent := True;
      end if;
   end Put_Header;
 
   ---------
   -- URL --
   ---------
 
   function URL return String is
 
      function Exists_And_Not_80 (Server_Port : String) return String;
      --  Returns ':' & Server_Port if Server_Port is not "80" and the empty
      --  string otherwise (80 is the default sever port).
 
      -----------------------
      -- Exists_And_Not_80 --
      -----------------------
 
      function Exists_And_Not_80 (Server_Port : String) return String is
      begin
         if Server_Port = "80" then
            return "";
         else
            return ':' & Server_Port;
         end if;
      end Exists_And_Not_80;
 
   --  Start of processing for URL
 
   begin
      Check_Environment;
 
      return "http://"
        & Metavariable (Server_Name)
        & Exists_And_Not_80 (Metavariable (Server_Port))
        & Metavariable (Script_Name);
   end URL;
 
   -----------
   -- Value --
   -----------
 
   function Value
     (Key      : String;
      Required : Boolean := False)
      return     String
   is
   begin
      Check_Environment;
 
      for K in 1 .. Key_Value_Table.Last loop
         if Key_Value_Table.Table (K).Key.all = Key then
            return Key_Value_Table.Table (K).Value.all;
         end if;
      end loop;
 
      if Required then
         raise Parameter_Not_Found;
      else
         return "";
      end if;
   end Value;
 
   -----------
   -- Value --
   -----------
 
   function Value (Position : Positive) return String is
   begin
      Check_Environment;
 
      if Position <= Key_Value_Table.Last then
         return Key_Value_Table.Table (Position).Value.all;
      else
         raise Parameter_Not_Found;
      end if;
   end Value;
 
begin
 
   Initialize;
 
end GNAT.CGI;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.