------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                     ADA.STRINGS.TEXT_BUFFERS.BOUNDED                     --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--            Copyright (C) 2020-2021, Free Software Foundation, Inc.       --
--                                                                          --
-- 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.Strings.UTF_Encoding.Conversions;
with Ada.Strings.UTF_Encoding.Strings;
with Ada.Strings.UTF_Encoding.Wide_Strings;
with Ada.Strings.UTF_Encoding.Wide_Wide_Strings;
package body Ada.Strings.Text_Buffers.Bounded is

   --  Pretty much the same as the Unbounded version, except where different.
   --
   --  One could imagine inventing an Input_Mapping generic analogous to
   --  the existing Output_Mapping generic to address the Get-related
   --  Bounded/Unbounded code duplication issues, but let's not. In the
   --  Output case, there was more substantial duplication and there were
   --  3 clients (Bounded, Unbounded, and Files) instead of 2.

   function Text_Truncated (Buffer : Buffer_Type) return Boolean is
     (Buffer.Truncated);

   function Get (Buffer : in out Buffer_Type) return String is
   --  If all characters are 7 bits, we don't need to decode;
   --  this is an optimization.
   --  Otherwise, if all are 8 bits, we need to decode to get Latin-1.
   --  Otherwise, the result is implementation defined, so we return a
   --  String encoded as UTF-8. Note that the RM says "if any character
   --  in the sequence is not defined in Character, the result is
   --  implementation-defined", so we are not obliged to decode ANY
   --  Latin-1 characters if ANY character is bigger than 8 bits.
   begin
      if Buffer.All_8_Bits and not Buffer.All_7_Bits then
         return UTF_Encoding.Strings.Decode (Get_UTF_8 (Buffer));
      else
         return Get_UTF_8 (Buffer);
      end if;
   end Get;

   function Wide_Get (Buffer : in out Buffer_Type) return Wide_String is
   begin
      return UTF_Encoding.Wide_Strings.Decode (Get_UTF_8 (Buffer));
   end Wide_Get;

   function Wide_Wide_Get (Buffer : in out Buffer_Type) return Wide_Wide_String
   is
   begin
      return UTF_Encoding.Wide_Wide_Strings.Decode (Get_UTF_8 (Buffer));
   end Wide_Wide_Get;

   function Get_UTF_8
     (Buffer : in out Buffer_Type) return UTF_Encoding.UTF_8_String
   is
   begin
      return
        Result : constant UTF_Encoding.UTF_8_String :=
          UTF_Encoding.UTF_8_String
            (Buffer.Chars (1 .. Text_Buffer_Count (Buffer.UTF_8_Length)))
      do
         --  Reset buffer to default initial value.
         declare
            Defaulted : Buffer_Type (0);

            --  If this aggregate becomes illegal due to new field, don't
            --  forget to add corresponding assignment statement below.
            Dummy : array (1 .. 0) of Buffer_Type (0) :=
              (others =>
                 (Max_Characters => 0, Chars => <>, Indentation => <>,
                  Indent_Pending => <>, UTF_8_Length => <>, UTF_8_Column => <>,
                  All_7_Bits     => <>, All_8_Bits => <>, Truncated => <>));
         begin
            Buffer.Indentation    := Defaulted.Indentation;
            Buffer.Indent_Pending := Defaulted.Indent_Pending;
            Buffer.UTF_8_Length   := Defaulted.UTF_8_Length;
            Buffer.UTF_8_Column   := Defaulted.UTF_8_Column;
            Buffer.All_7_Bits     := Defaulted.All_7_Bits;
            Buffer.All_8_Bits     := Defaulted.All_8_Bits;
            Buffer.Truncated      := Defaulted.Truncated;
         end;
      end return;
   end Get_UTF_8;

   function Wide_Get_UTF_16
     (Buffer : in out Buffer_Type) return UTF_Encoding.UTF_16_Wide_String
   is
   begin
      return
        UTF_Encoding.Conversions.Convert
          (Get_UTF_8 (Buffer), Input_Scheme => UTF_Encoding.UTF_8);
   end Wide_Get_UTF_16;

   procedure Put_UTF_8_Implementation
     (Buffer : in out Root_Buffer_Type'Class;
      Item   : UTF_Encoding.UTF_8_String)
   is
      procedure Buffer_Type_Implementation (Buffer : in out Buffer_Type);
      --  View the passed-in Buffer parameter as being of type Buffer_Type,
      --  not of Root_Buffer_Type'Class.

      procedure Buffer_Type_Implementation (Buffer : in out Buffer_Type) is
      begin
         for Char of Item loop
            if Buffer.UTF_8_Length = Integer (Buffer.Max_Characters) then
               Buffer.Truncated := True;
               return;
            end if;

            Buffer.All_7_Bits := @ and then Character'Pos (Char) < 128;

            Buffer.UTF_8_Length                                    := @ + 1;
            Buffer.UTF_8_Column                                    := @ + 1;
            Buffer.Chars (Text_Buffer_Count (Buffer.UTF_8_Length)) := Char;
         end loop;
      end Buffer_Type_Implementation;
   begin
      if Item'Length > 0 then
         Buffer_Type_Implementation (Buffer_Type (Buffer));
      end if;
   end Put_UTF_8_Implementation;

end Ada.Strings.Text_Buffers.Bounded;
