------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                    G N A T . D E C O D E _ S T R I N G                   --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                     Copyright (C) 2007-2021, 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.      --
--                                                                          --
------------------------------------------------------------------------------

--  This package provides a utility routine for converting from an encoded
--  string to a corresponding Wide_String or Wide_Wide_String value.

with Interfaces; use Interfaces;

with System.WCh_Cnv; use System.WCh_Cnv;
with System.WCh_Con; use System.WCh_Con;

package body GNAT.Decode_String is

   -----------------------
   -- Local Subprograms --
   -----------------------

   procedure Bad;
   pragma No_Return (Bad);
   --  Raise error for bad encoding

   procedure Past_End;
   pragma No_Return (Past_End);
   --  Raise error for off end of string

   ---------
   -- Bad --
   ---------

   procedure Bad is
   begin
      raise Constraint_Error with
        "bad encoding or character out of range";
   end Bad;

   ---------------------------
   -- Decode_Wide_Character --
   ---------------------------

   procedure Decode_Wide_Character
     (Input  : String;
      Ptr    : in out Natural;
      Result : out Wide_Character)
   is
      Char : Wide_Wide_Character;
   begin
      Decode_Wide_Wide_Character (Input, Ptr, Char);

      if Wide_Wide_Character'Pos (Char) > 16#FFFF# then
         Bad;
      else
         Result := Wide_Character'Val (Wide_Wide_Character'Pos (Char));
      end if;
   end Decode_Wide_Character;

   ------------------------
   -- Decode_Wide_String --
   ------------------------

   function Decode_Wide_String (S : String) return Wide_String is
      Result : Wide_String (1 .. S'Length);
      Length : Natural;
   begin
      Decode_Wide_String (S, Result, Length);
      return Result (1 .. Length);
   end Decode_Wide_String;

   procedure Decode_Wide_String
     (S      : String;
      Result : out Wide_String;
      Length : out Natural)
   is
      Ptr : Natural;

   begin
      Ptr := S'First;
      Length := 0;
      while Ptr <= S'Last loop
         if Length >= Result'Last then
            Past_End;
         end if;

         Length := Length + 1;
         Decode_Wide_Character (S, Ptr, Result (Length));
      end loop;
   end Decode_Wide_String;

   --------------------------------
   -- Decode_Wide_Wide_Character --
   --------------------------------

   procedure Decode_Wide_Wide_Character
     (Input  : String;
      Ptr    : in out Natural;
      Result : out Wide_Wide_Character)
   is
      C : Character;

      function In_Char return Character;
      pragma Inline (In_Char);
      --  Function to get one input character

      -------------
      -- In_Char --
      -------------

      function In_Char return Character is
      begin
         if Ptr <= Input'Last then
            Ptr := Ptr + 1;
            return Input (Ptr - 1);
         else
            Past_End;
         end if;
      end In_Char;

   --  Start of processing for Decode_Wide_Wide_Character

   begin
      C := In_Char;

      --  Special fast processing for UTF-8 case

      if Encoding_Method = WCEM_UTF8 then
         UTF8 : declare
            U : Unsigned_32;
            W : Unsigned_32;

            procedure Get_UTF_Byte;
            pragma Inline (Get_UTF_Byte);
            --  Used to interpret 2#10xxxxxx# continuation byte in UTF-8 mode.
            --  Reads a byte, and raises CE if the first two bits are not 10.
            --  Otherwise shifts W 6 bits left and or's in the 6 xxxxxx bits.

            ------------------
            -- Get_UTF_Byte --
            ------------------

            procedure Get_UTF_Byte is
            begin
               U := Unsigned_32 (Character'Pos (In_Char));

               if (U and 2#11000000#) /= 2#10_000000# then
                  Bad;
               end if;

               W := Shift_Left (W, 6) or (U and 2#00111111#);
            end Get_UTF_Byte;

         --  Start of processing for UTF8 case

         begin
            --  Note: for details of UTF8 encoding see RFC 3629

            U := Unsigned_32 (Character'Pos (C));

            --  16#00_0000#-16#00_007F#: 0xxxxxxx

            if (U and 2#10000000#) = 2#00000000# then
               Result := Wide_Wide_Character'Val (Character'Pos (C));

            --  16#00_0080#-16#00_07FF#: 110xxxxx 10xxxxxx

            elsif (U and 2#11100000#) = 2#110_00000# then
               W := U and 2#00011111#;
               Get_UTF_Byte;

               if W not in 16#00_0080# .. 16#00_07FF# then
                  Bad;
               end if;

               Result := Wide_Wide_Character'Val (W);

            --  16#00_0800#-16#00_ffff#: 1110xxxx 10xxxxxx 10xxxxxx

            elsif (U and 2#11110000#) = 2#1110_0000# then
               W := U and 2#00001111#;
               Get_UTF_Byte;
               Get_UTF_Byte;

               if W not in 16#00_0800# .. 16#00_FFFF# then
                  Bad;
               end if;

               Result := Wide_Wide_Character'Val (W);

            --  16#01_0000#-16#10_FFFF#: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

            elsif (U and 2#11111000#) = 2#11110_000# then
               W := U and 2#00000111#;

               for K in 1 .. 3 loop
                  Get_UTF_Byte;
               end loop;

               if W not in 16#01_0000# .. 16#10_FFFF# then
                  Bad;
               end if;

               Result := Wide_Wide_Character'Val (W);

            --  16#0020_0000#-16#03FF_FFFF#: 111110xx 10xxxxxx 10xxxxxx
            --                               10xxxxxx 10xxxxxx

            elsif (U and 2#11111100#) = 2#111110_00# then
               W := U and 2#00000011#;

               for K in 1 .. 4 loop
                  Get_UTF_Byte;
               end loop;

               if W not in 16#0020_0000# .. 16#03FF_FFFF# then
                  Bad;
               end if;

               Result := Wide_Wide_Character'Val (W);

            --  All other cases are invalid, note that this includes:

            --  16#0400_0000#-16#7FFF_FFFF#: 1111110x 10xxxxxx 10xxxxxx
            --                               10xxxxxx 10xxxxxx 10xxxxxx

            --  since Wide_Wide_Character does not include code values
            --  greater than 16#03FF_FFFF#.

            else
               Bad;
            end if;
         end UTF8;

      --  All encoding functions other than UTF-8

      else
         Non_UTF8 : declare
            function Char_Sequence_To_UTF is
              new Char_Sequence_To_UTF_32 (In_Char);

         begin
            --  For brackets, must test for specific case of [ not followed by
            --  quotation, where we must not call Char_Sequence_To_UTF, but
            --  instead just return the bracket unchanged.

            if Encoding_Method = WCEM_Brackets
              and then C = '['
              and then (Ptr > Input'Last or else Input (Ptr) /= '"')
            then
               Result := '[';

            --  All other cases including [" with Brackets

            else
               Result :=
                 Wide_Wide_Character'Val
                   (Char_Sequence_To_UTF (C, Encoding_Method));
            end if;
         end Non_UTF8;
      end if;
   end Decode_Wide_Wide_Character;

   -----------------------------
   -- Decode_Wide_Wide_String --
   -----------------------------

   function Decode_Wide_Wide_String (S : String) return Wide_Wide_String is
      Result : Wide_Wide_String (1 .. S'Length);
      Length : Natural;
   begin
      Decode_Wide_Wide_String (S, Result, Length);
      return Result (1 .. Length);
   end Decode_Wide_Wide_String;

   procedure Decode_Wide_Wide_String
     (S      : String;
      Result : out Wide_Wide_String;
      Length : out Natural)
   is
      Ptr : Natural;

   begin
      Ptr := S'First;
      Length := 0;
      while Ptr <= S'Last loop
         if Length >= Result'Last then
            Past_End;
         end if;

         Length := Length + 1;
         Decode_Wide_Wide_Character (S, Ptr, Result (Length));
      end loop;
   end Decode_Wide_Wide_String;

   -------------------------
   -- Next_Wide_Character --
   -------------------------

   procedure Next_Wide_Character (Input : String; Ptr : in out Natural) is
      Discard : Wide_Character;
   begin
      Decode_Wide_Character (Input, Ptr, Discard);
   end Next_Wide_Character;

   ------------------------------
   -- Next_Wide_Wide_Character --
   ------------------------------

   procedure Next_Wide_Wide_Character (Input : String; Ptr : in out Natural) is
      Discard : Wide_Wide_Character;
   begin
      Decode_Wide_Wide_Character (Input, Ptr, Discard);
   end Next_Wide_Wide_Character;

   --------------
   -- Past_End --
   --------------

   procedure Past_End is
   begin
      raise Constraint_Error with "past end of string";
   end Past_End;

   -------------------------
   -- Prev_Wide_Character --
   -------------------------

   procedure Prev_Wide_Character (Input : String; Ptr : in out Natural) is
   begin
      if Ptr > Input'Last + 1 then
         Past_End;
      end if;

      --  Special efficient encoding for UTF-8 case

      if Encoding_Method = WCEM_UTF8 then
         UTF8 : declare
            U : Unsigned_32;

            procedure Getc;
            pragma Inline (Getc);
            --  Gets the character at Input (Ptr - 1) and returns code in U as
            --  Unsigned_32 value. On return Ptr is decremented by one.

            procedure Skip_UTF_Byte;
            pragma Inline (Skip_UTF_Byte);
            --  Checks that U is 2#10xxxxxx# and then calls Get

            ----------
            -- Getc --
            ----------

            procedure Getc is
            begin
               if Ptr <= Input'First then
                  Past_End;
               else
                  Ptr := Ptr - 1;
                  U := Unsigned_32 (Character'Pos (Input (Ptr)));
               end if;
            end Getc;

            -------------------
            -- Skip_UTF_Byte --
            -------------------

            procedure Skip_UTF_Byte is
            begin
               if (U and 2#11000000#) = 2#10_000000# then
                  Getc;
               else
                  Bad;
               end if;
            end Skip_UTF_Byte;

         --  Start of processing for UTF-8 case

         begin
            --  16#00_0000#-16#00_007F#: 0xxxxxxx

            Getc;

            if (U and 2#10000000#) = 2#00000000# then
               return;

            --  16#00_0080#-16#00_07FF#: 110xxxxx 10xxxxxx

            else
               Skip_UTF_Byte;

               if (U and 2#11100000#) = 2#110_00000# then
                  return;

               --  16#00_0800#-16#00_ffff#: 1110xxxx 10xxxxxx 10xxxxxx

               else
                  Skip_UTF_Byte;

                  if (U and 2#11110000#) = 2#1110_0000# then
                     return;

                     --  Any other code is invalid, note that this includes:

                     --  16#01_0000#-16#10_FFFF#: 11110xxx 10xxxxxx 10xxxxxx
                     --                           10xxxxxx

                     --  16#0020_0000#-16#03FF_FFFF#: 111110xx 10xxxxxx
                     --                               10xxxxxx 10xxxxxx
                     --                               10xxxxxx

                     --  16#0400_0000#-16#7FFF_FFFF#: 1111110x 10xxxxxx
                     --                               10xxxxxx 10xxxxxx
                     --                               10xxxxxx 10xxxxxx

                     --  since Wide_Character does not allow codes > 16#FFFF#

                  else
                     Bad;
                  end if;
               end if;
            end if;
         end UTF8;

      --  Special efficient encoding for brackets case

      elsif Encoding_Method = WCEM_Brackets then
         Brackets : declare
            P : Natural;
            S : Natural;

         begin
            --  See if we have "] at end positions

            if Ptr > Input'First + 1
              and then Input (Ptr - 1) = ']'
              and then Input (Ptr - 2) = '"'
            then
               P := Ptr - 2;

               --  Loop back looking for [" at start

               while P >= Ptr - 10 loop
                  if P <= Input'First + 1 then
                     Bad;

                  elsif Input (P - 1) = '"'
                    and then Input (P - 2) = '['
                  then
                     --  Found ["..."], scan forward to check it

                     S := P - 2;
                     P := S;
                     Next_Wide_Character (Input, P);

                     --  OK if at original pointer, else error

                     if P = Ptr then
                        Ptr := S;
                        return;
                     else
                        Bad;
                     end if;
                  end if;

                  P := P - 1;
               end loop;

               --  Falling through loop means more than 8 chars between the
               --  enclosing brackets (or simply a missing left bracket)

               Bad;

            --  Here if no bracket sequence present

            else
               if Ptr = Input'First then
                  Past_End;
               else
                  Ptr := Ptr - 1;
               end if;
            end if;
         end Brackets;

      --  Non-UTF-8/Brackets. These are the inefficient cases where we have to
      --  go to the start of the string and skip forwards till Ptr matches.

      else
         Non_UTF_Brackets : declare
            Discard : Wide_Character;
            PtrS    : Natural;
            PtrP    : Natural;

         begin
            PtrS := Input'First;

            if Ptr <= PtrS then
               Past_End;
            end if;

            loop
               PtrP := PtrS;
               Decode_Wide_Character (Input, PtrS, Discard);

               if PtrS = Ptr then
                  Ptr := PtrP;
                  return;

               elsif PtrS > Ptr then
                  Bad;
               end if;
            end loop;

         exception
            when Constraint_Error =>
               Bad;
         end Non_UTF_Brackets;
      end if;
   end Prev_Wide_Character;

   ------------------------------
   -- Prev_Wide_Wide_Character --
   ------------------------------

   procedure Prev_Wide_Wide_Character (Input : String; Ptr : in out Natural) is
   begin
      if Ptr > Input'Last + 1 then
         Past_End;
      end if;

      --  Special efficient encoding for UTF-8 case

      if Encoding_Method = WCEM_UTF8 then
         UTF8 : declare
            U : Unsigned_32;

            procedure Getc;
            pragma Inline (Getc);
            --  Gets the character at Input (Ptr - 1) and returns code in U as
            --  Unsigned_32 value. On return Ptr is decremented by one.

            procedure Skip_UTF_Byte;
            pragma Inline (Skip_UTF_Byte);
            --  Checks that U is 2#10xxxxxx# and then calls Get

            ----------
            -- Getc --
            ----------

            procedure Getc is
            begin
               if Ptr <= Input'First then
                  Past_End;
               else
                  Ptr := Ptr - 1;
                  U := Unsigned_32 (Character'Pos (Input (Ptr)));
               end if;
            end Getc;

            -------------------
            -- Skip_UTF_Byte --
            -------------------

            procedure Skip_UTF_Byte is
            begin
               if (U and 2#11000000#) = 2#10_000000# then
                  Getc;
               else
                  Bad;
               end if;
            end Skip_UTF_Byte;

         --  Start of processing for UTF-8 case

         begin
            --  16#00_0000#-16#00_007F#: 0xxxxxxx

            Getc;

            if (U and 2#10000000#) = 2#00000000# then
               return;

            --  16#00_0080#-16#00_07FF#: 110xxxxx 10xxxxxx

            else
               Skip_UTF_Byte;

               if (U and 2#11100000#) = 2#110_00000# then
                  return;

               --  16#00_0800#-16#00_ffff#: 1110xxxx 10xxxxxx 10xxxxxx

               else
                  Skip_UTF_Byte;

                  if (U and 2#11110000#) = 2#1110_0000# then
                     return;

                  --  16#01_0000#-16#10_FFFF#: 11110xxx 10xxxxxx 10xxxxxx
                  --                           10xxxxxx

                  else
                     Skip_UTF_Byte;

                     if (U and 2#11111000#) = 2#11110_000# then
                        return;

                     --  16#0020_0000#-16#03FF_FFFF#: 111110xx 10xxxxxx
                     --                               10xxxxxx 10xxxxxx
                     --                               10xxxxxx

                     else
                        Skip_UTF_Byte;

                        if (U and 2#11111100#) = 2#111110_00# then
                           return;

                        --  Any other code is invalid, note that this includes:

                        --  16#0400_0000#-16#7FFF_FFFF#: 1111110x 10xxxxxx
                        --                               10xxxxxx 10xxxxxx
                        --                               10xxxxxx 10xxxxxx

                        --  since Wide_Wide_Character does not allow codes
                        --  greater than 16#03FF_FFFF#

                        else
                           Bad;
                        end if;
                     end if;
                  end if;
               end if;
            end if;
         end UTF8;

      --  Special efficient encoding for brackets case

      elsif Encoding_Method = WCEM_Brackets then
         Brackets : declare
            P : Natural;
            S : Natural;

         begin
            --  See if we have "] at end positions

            if Ptr > Input'First + 1
              and then Input (Ptr - 1) = ']'
              and then Input (Ptr - 2) = '"'
            then
               P := Ptr - 2;

               --  Loop back looking for [" at start

               while P >= Ptr - 10 loop
                  if P <= Input'First + 1 then
                     Bad;

                  elsif Input (P - 1) = '"'
                    and then Input (P - 2) = '['
                  then
                     --  Found ["..."], scan forward to check it

                     S := P - 2;
                     P := S;
                     Next_Wide_Wide_Character (Input, P);

                     --  OK if at original pointer, else error

                     if P = Ptr then
                        Ptr := S;
                        return;
                     else
                        Bad;
                     end if;
                  end if;

                  P := P - 1;
               end loop;

               --  Falling through loop means more than 8 chars between the
               --  enclosing brackets (or simply a missing left bracket)

               Bad;

            --  Here if no bracket sequence present

            else
               if Ptr = Input'First then
                  Past_End;
               else
                  Ptr := Ptr - 1;
               end if;
            end if;
         end Brackets;

      --  Non-UTF-8/Brackets. These are the inefficient cases where we have to
      --  go to the start of the string and skip forwards till Ptr matches.

      else
         Non_UTF8_Brackets : declare
            Discard : Wide_Wide_Character;
            PtrS    : Natural;
            PtrP    : Natural;

         begin
            PtrS := Input'First;

            if Ptr <= PtrS then
               Past_End;
            end if;

            loop
               PtrP := PtrS;
               Decode_Wide_Wide_Character (Input, PtrS, Discard);

               if PtrS = Ptr then
                  Ptr := PtrP;
                  return;

               elsif PtrS > Ptr then
                  Bad;
               end if;
            end loop;

         exception
            when Constraint_Error =>
               Bad;
         end Non_UTF8_Brackets;
      end if;
   end Prev_Wide_Wide_Character;

   --------------------------
   -- Validate_Wide_String --
   --------------------------

   function Validate_Wide_String (S : String) return Boolean is
      Ptr : Natural;

   begin
      Ptr := S'First;
      while Ptr <= S'Last loop
         Next_Wide_Character (S, Ptr);
      end loop;

      return True;

   exception
      when Constraint_Error =>
         return False;
   end Validate_Wide_String;

   -------------------------------
   -- Validate_Wide_Wide_String --
   -------------------------------

   function Validate_Wide_Wide_String (S : String) return Boolean is
      Ptr : Natural;

   begin
      Ptr := S'First;
      while Ptr <= S'Last loop
         Next_Wide_Wide_Character (S, Ptr);
      end loop;

      return True;

   exception
      when Constraint_Error =>
         return False;
   end Validate_Wide_Wide_String;

end GNAT.Decode_String;
