package body Character_IO is
   LM: constant Character := ASCII.LF;

   procedure Get_Line(File : in Character_IO.File_Type;
                      Item : out String;
                      Last : out Natural;
                      New_Line : out Boolean) is
      C: Character;
   begin
      New_Line := False;
      Last := Item'First - 1;
      if Last >= Item'Last then
         return;
      end if;
      if Character_IO.End_Of_File(File) then
         raise Character_IO.End_Error;
      end if;
      loop
         Character_IO.Read(File, C);
         if C = LM then
            New_Line := True;
            return;
         end if;
         Last := Last + 1;
         Item(Last) := C;
         if Last = Item'Last then
            return;
         end if;
         exit when Character_IO.End_Of_File(File);
      end loop;
   end;

   function Get_Line (File : Character_IO.File_Type;
                      New_Line : out Boolean) return String is
      Buffer : String (1 .. 500);
      Last   : Natural;

      function Get_Rest (S : String) return String is
         Buffer : String (1 .. S'Length);
         Last   : Natural;
      begin
         Get_Line (File, Buffer, Last, New_Line);
         declare
            R : constant String := S & Buffer (1 .. Last);
         begin
            if Last < Buffer'Last then
               return R;
            else
               return Get_Rest (R);
            end if;
         end;
      end Get_Rest;

   begin
      Get_Line (File, Buffer, Last, New_Line);

      if Last < Buffer'Last then
         return Buffer (1 .. Last);
      else
         return Get_Rest (Buffer (1 .. Last));
      end if;
   end Get_Line;

   function Get_Line(File : in Character_IO.File_Type) return String is
      New_Line : Boolean;
   begin
      return Get_Line(File, New_Line);
   end Get_Line;

   procedure Put_Line(File : in Character_IO.File_Type;
                      Item : in String;
                      New_Line : Boolean := True) is
   begin
      for C of Item loop
         Character_IO.Write(File, C);
      end loop;
      if New_Line then
         Character_IO.Write(File, LM);
      end if;
   end;
end;
