Skip to content

Instantly share code, notes, and snippets.

@jesselang
Created January 24, 2016 18:06
Show Gist options
  • Save jesselang/f432f4ae6bfb41e83aa2 to your computer and use it in GitHub Desktop.
Save jesselang/f432f4ae6bfb41e83aa2 to your computer and use it in GitHub Desktop.
I wrote this in May of 2010, and don't remember what it does, but better it being forgotten here than on a hard drive.
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Streams.Stream_IO;
use Ada.Streams;
procedure Verify_UTF is
First_Word : constant Stream_Element_Array (1 .. 2) := (16#fe#, 16#ff#); -- http://en.wikipedia.org/wiki/Byte_order_mark
Second_Word : constant Stream_Element_Array (1 .. 2) := (16#00#, 16#22#);
Swap_Endian : Boolean := False;
Input : Stream_IO.File_Type;
Output : Stream_IO.File_Type;
Word : Stream_Element_Array (1 .. 2);
Buffer : Stream_Element_Array (1 .. 256);
Last : Stream_Element_Offset;
begin -- Verify_UTF
if Ada.Command_Line.Argument_Count /= 2 then
Ada.Text_IO.Put_Line (File => Ada.Text_IO.Standard_Error, Item => "Usage: verifyutf <in-file> <out-file>");
else
Handle_Input_Error : begin
Stream_IO.Open (File => Input, Mode => Stream_IO.In_File, Name => Ada.Command_Line.Argument (1) );
exception -- Handle_Input_Error
when Stream_IO.Name_Error | Stream_IO.Status_Error | Stream_IO.Use_Error =>
Ada.Text_IO.Put_Line (File => Ada.Text_IO.Standard_Error, Item => "Error: Could not open input file.");
raise;
end Handle_Input_Error;
-- Read and verify 2-word (32 bits) UTF header.
Stream_IO.Read (File => Input, Item => Word, Last => Last);
if Word /= First_Word then
if Word (1) = First_Word (2) and Word (2) = First_Word (1) then
Swap_Endian := True;
else
Ada.Text_IO.Put_Line
(File => Ada.Text_IO.Standard_Error, Item => "Error: This file does not appear to have a UTF header.");
Ada.Command_Line.Set_Exit_Status (2);
Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, Stream_Element'Image (Word (1) ) & Stream_Element'Image (Word (2) ) &
" - " & Stream_Element'Image (First_Word (1) ) & Stream_Element'Image (First_Word (2) ) );
end if;
else
Open_Or_Create : begin
Stream_IO.Open (File => Output, Mode => Stream_IO.Out_File, Name => Ada.Command_Line.Argument (2) );
exception -- Open_Or_Create
when Stream_IO.Name_Error | Stream_IO.Status_Error | Stream_IO.Use_Error =>
Handle_Output_Error : begin
Stream_IO.Create (File => Output, Mode => Stream_IO.Out_File, Name => Ada.Command_Line.Argument (2) );
exception -- Handle_Output_Error
when Stream_IO.Name_Error | Stream_IO.Status_Error | Stream_IO.Use_Error =>
Ada.Text_IO.Put_Line
(File => Ada.Text_IO.Standard_Error, Item => "Error: Could not open or create output file.");
-- Could close Input here, but the program is exiting anyway.
raise;
end Handle_Output_Error;
end Open_Or_Create;
Stream_IO.Write (File => Output, Item => Word);
-- Verify the second word, or else insert the valid second word to the output.
Stream_IO.Read (File => Input, Item => Word, Last => Last);
if Word /= Second_Word and (Swap_Endian and Word (1) /= First_Word (2) and Word (2) /= First_Word (1) ) then
Ada.Text_IO.Put_Line (Ada.Text_IO.Standard_Error, Stream_Element'Image (Word (1) ) & Stream_Element'Image (Word (2) ) &
" - " & Stream_Element'Image (Second_Word (1) ) & Stream_Element'Image (Second_Word (2) ) );
Stream_IO.Write (File => Output, Item => Second_Word);
end if;
Stream_IO.Write (File => Output, Item => Word);
Copy_Remaining : loop
exit Copy_Remaining when Stream_IO.End_Of_File (Input);
Stream_IO.Read (File => Input, Item => Buffer, Last => Last);
if Last > 0 then
Stream_IO.Write (File => Output, Item => Buffer (Buffer'First .. Last) );
end if;
end loop Copy_Remaining;
end if;
if Stream_IO.Is_Open (Output) then
Stream_IO.Close (File => Output);
end if;
if Stream_IO.Is_Open (Input) then
Stream_IO.Close (File => Input);
end if;
end if;
exception -- Verify_UTF
when Stream_IO.Name_Error | Stream_IO.Use_Error =>
Ada.Command_Line.Set_Exit_Status (1);
end Verify_UTF;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment