-------------------------------------------------------------------------------
4) Reading Textfiles not written by Ada
This is all very well as long as the file was created by Ada.Text_IO. If the
file was created by other means - for example a text editor - than it might
be that the last line is missing a line terminator.
Remember the case where the line has exactly the length of the buffer. With
the first Get_Line your read all the characters, with the next Get_Line you
read 0 characters.
This works because with the first read reads all characters excluding the line
terminator. The second one will read 0 characters and consume the line
terminator.
However, in the special case of the last line missing a line terminator an
"End_Of_File" exception might be raised instead.
The language lawyers think this is a compiler bug and an implicid line
terminator should be provided by the library. Still, this does not help us
and we need a workaround.
The following two functions have been taken from AdaCL (adacl.sf.net):
package S_U renames Ada.Strings.Unbounded;
package IO renames Ada.Text_IO;
BufferSize : constant := 2000;
function Get_Line (
File : in IO.File_Type)
return
String
is
Buffer : String (1 .. BufferSize);
Last : Natural;
begin
IO.Get_Line (
File => File,
Item => Buffer,
Last => Last);
if Last < Buffer'Last then
return Buffer (1 .. Last);
elsif IO.End_Of_File (File) then
return Buffer;
else
return Buffer & Get_Line (File);
end if;
end Get_Line;
function Get_Line (
File : in IO.File_Type)
return
S_U.Unbounded_String
is
Retval : S_U.Unbounded_String := S_U.Null_Unbounded_String;
Item : String (1 .. BufferSize);
Last : Natural;
begin
GetWholeLine :
loop
IO.Get_Line (
File => File,
Item => Item,
Last => Last);
S_U.Append (
Source => Retval,
New_Item => Item (1 .. Last));
exit GetWholeLine when Last < Item'Last
or IO.End_Of_File (File);
end loop GetWholeLine;
return Retval;
end Get_Line;
The workaround lies in checking for for End_Of_File after the Get_Line. If
End_Of_File is reached the last line has been read completly and is returned.
Any further attempt to read from that file will raise the "End_Of_File"
exception.
On Ada implemetation which provide an implicid line terminator the workaround
will only consume a bit of performace for the unneded test but will do no
harm otherwise.
-------------------------------------------------------------------------------
|