-- -- Copyright (C) 2020-2023, AdaCore -- -- SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -- with Ada.Calendar; with Ada.Streams.Stream_IO; with Interfaces; with VSS.Command_Line; with VSS.JSON.Pull_Readers.Simple; with VSS.JSON.Pull_Readers.JSON5; with VSS.JSON.Streams; with VSS.Strings.Conversions; with VSS.Strings.Formatters.Booleans; with VSS.Strings.Formatters.Generic_Enumerations; with VSS.Strings.Formatters.Strings; with VSS.Strings.Templates; with VSS.String_Vectors; with VSS.Text_Streams.File_Output; with VSS.Text_Streams.Standards; with Tests_Text_Streams; procedure Test_JSON_Pull_Reader is -- use all type VSS.JSON.Pull_Readers.JSON_Event_Kind; use all type VSS.JSON.Pull_Readers.JSON_Reader_Error; package Command_Line is procedure Initialize; end Command_Line; package Options is Performance : Boolean := False; Incremental : Boolean := False; JSON5 : Boolean := False; Input_File_Name : VSS.Strings.Virtual_String; Output_File_Name : VSS.Strings.Virtual_String; end Options; ----------------- -- Command_Lne -- ----------------- package body Command_Line is Incremental_Option : constant VSS.Command_Line.Binary_Option := (Short_Name => <>, Long_Name => "incremental", Description => "Activate incremental parsing mode"); Performance_Option : constant VSS.Command_Line.Binary_Option := (Short_Name => <>, Long_Name => "performance", Description => "Report performance statistic"); JSON5_Option : constant VSS.Command_Line.Binary_Option := (Short_Name => <>, Long_Name => "json5", Description => "Enable JSON5"); Input_File_Option : constant VSS.Command_Line.Positional_Option := (Name => "input", Description => "Name of the input file"); Output_File_Option : constant VSS.Command_Line.Positional_Option := (Name => "output", Description => "Name of the input file"); procedure Register_Switches; ---------------- -- Initialize -- ---------------- procedure Initialize is Positionals : VSS.String_Vectors.Virtual_String_Vector; begin Register_Switches; VSS.Command_Line.Process; Options.Incremental := VSS.Command_Line.Is_Specified (Incremental_Option); Options.Performance := VSS.Command_Line.Is_Specified (Performance_Option); Options.JSON5 := VSS.Command_Line.Is_Specified (JSON5_Option); Positionals := VSS.Command_Line.Positional_Arguments; if Positionals.Length = 0 then VSS.Command_Line.Report_Error ("Input file not specified"); end if; if Positionals.Length = 1 then VSS.Command_Line.Report_Error ("Output file not specified"); end if; Options.Input_File_Name := VSS.Command_Line.Value (Input_File_Option); Options.Output_File_Name := VSS.Command_Line.Value (Output_File_Option); end Initialize; ----------------------- -- Register_Switches -- ----------------------- procedure Register_Switches is begin VSS.Command_Line.Add_Option (Incremental_Option); VSS.Command_Line.Add_Option (Performance_Option); VSS.Command_Line.Add_Option (JSON5_Option); VSS.Command_Line.Add_Option (Input_File_Option); VSS.Command_Line.Add_Option (Output_File_Option); end Register_Switches; end Command_Line; package JSON_Number_Kind_Formatters is new VSS.Strings.Formatters.Generic_Enumerations (VSS.JSON.JSON_Number_Kind); package JSON_Stream_Element_Kind_Formatters is new VSS.Strings.Formatters.Generic_Enumerations (VSS.JSON.Streams.JSON_Stream_Element_Kind); package JSON_Reader_Error_Formatters is new VSS.Strings.Formatters.Generic_Enumerations (VSS.JSON.Pull_Readers.JSON_Reader_Error); Input : aliased Tests_Text_Streams.Memory_UTF8_Input_Stream; Count : Natural := 0; Output : VSS.Text_Streams.File_Output.File_Output_Text_Stream; Error : VSS.Text_Streams.Output_Text_Stream'Class renames VSS.Text_Streams.Standards.Standard_Error; begin Command_Line.Initialize; Output.Create (Options.Output_File_Name); declare File : Ada.Streams.Stream_IO.File_Type; Aux : Ada.Streams.Stream_Element_Array (1 .. 1_024); Last : Ada.Streams.Stream_Element_Offset; begin Ada.Streams.Stream_IO.Open (File, Ada.Streams.Stream_IO.In_File, VSS.Strings.Conversions.To_UTF_8_String (Options.Input_File_Name), "text_translation=no"); while not Ada.Streams.Stream_IO.End_Of_File (File) loop Ada.Streams.Stream_IO.Read (File, Aux, Last); for J in Aux'First .. Last loop Input.Buffer.Append (Aux (J)); end loop; end loop; Ada.Streams.Stream_IO.Close (File); end; declare use type Ada.Calendar.Time; function Setup_Reader return VSS.JSON.Pull_Readers.JSON_Pull_Reader'Class; ------------------ -- Setup_Reader -- ------------------ function Setup_Reader return VSS.JSON.Pull_Readers.JSON_Pull_Reader'Class is begin Input.Set_Incremental (Options.Incremental); if Options.JSON5 then return Result : VSS.JSON.Pull_Readers.JSON5.JSON5_Pull_Reader do Result.Set_Stream (Input'Unchecked_Access); end return; else return Result : VSS.JSON.Pull_Readers.Simple.JSON_Simple_Pull_Reader do Result.Set_Stream (Input'Unchecked_Access); end return; end if; end Setup_Reader; Reader : VSS.JSON.Pull_Readers.JSON_Pull_Reader'Class := Setup_Reader; Start : constant Ada.Calendar.Time := Ada.Calendar.Clock; Success : Boolean := True; begin while not Reader.At_End loop Reader.Read_Next; case Reader.Element_Kind is when VSS.JSON.Streams.Invalid => if Reader.Error /= Premature_End_Of_Document then Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {} ""{}""").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), JSON_Reader_Error_Formatters.Image (Reader.Error), VSS.Strings.Formatters.Strings.Image (Reader.Error_Message)), Success); if Reader.Error /= Not_Valid then raise Program_Error; end if; elsif not Options.Incremental then raise Program_Error; else Count := Count + 1; if Count > 1_000 then raise Program_Error; end if; end if; when VSS.JSON.Streams.Key_Name => Count := 0; if not Options.Performance then Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} ""{}""").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), VSS.Strings.Formatters.Strings.Image (Reader.Key_Name)), Success); end if; when VSS.JSON.Streams.String_Value => Count := 0; if not Options.Performance then Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} ""{}""").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), VSS.Strings.Formatters.Strings.Image (Reader.String_Value)), Success); end if; when VSS.JSON.Streams.Number_Value => Count := 0; if not Options.Performance then case Reader.Number_Value.Kind is when VSS.JSON.None => Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {} {}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), JSON_Number_Kind_Formatters.Image (Reader.Number_Value.Kind), VSS.Strings.Formatters.Strings.Image (Reader.Number_Value.String_Value)), Success); when VSS.JSON.JSON_Integer => Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {} {} {}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), JSON_Number_Kind_Formatters.Image (Reader.Number_Value.Kind), VSS.Strings.Formatters.Strings.Image (Reader.Number_Value.String_Value), VSS.Strings.Formatters.Strings.Image (VSS.Strings.To_Virtual_String (Interfaces.Integer_64'Wide_Wide_Image (Reader.Number_Value.Integer_Value)))), Success); when VSS.JSON.JSON_Float => Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {} {} {}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), JSON_Number_Kind_Formatters.Image (Reader.Number_Value.Kind), VSS.Strings.Formatters.Strings.Image (Reader.Number_Value.String_Value), VSS.Strings.Formatters.Strings.Image (VSS.Strings.To_Virtual_String (Interfaces.IEEE_Float_64'Wide_Wide_Image (Reader.Number_Value.Float_Value)))), Success); when VSS.JSON.Out_Of_Range => Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {} {}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), JSON_Number_Kind_Formatters.Image (Reader.Number_Value.Kind), VSS.Strings.Formatters.Strings.Image (Reader.Number_Value.String_Value)), Success); end case; end if; when VSS.JSON.Streams.Boolean_Value => Count := 0; if not Options.Performance then Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{} {}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind), VSS.Strings.Formatters.Booleans.Image (Reader.Boolean_Value)), Success); end if; when others => Count := 0; if not Options.Performance then Output.Put_Line (VSS.Strings.Templates.To_Virtual_String_Template ("{}").Format (JSON_Stream_Element_Kind_Formatters.Image (Reader.Element_Kind)), Success); end if; end case; end loop; if Options.Performance then Error.Put_Line (VSS.Strings.To_Virtual_String (Duration'Wide_Wide_Image (Ada.Calendar.Clock - Start)), Success); end if; end; Output.Close; end Test_JSON_Pull_Reader;