|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 7663 (0x1def)
Types: TextFile
Names: »B«
└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
└─⟦5cb1d1d7f⟧ »DATA«
└─⟦3b1ee7bd8⟧
└─⟦this⟧
with Io;
with Log;
with Io_Exceptions;
package body Tape_Utils is
Tape : Device;
function Obtain (Mode : Io_Mode;
Format : String;
Volume : String := "";
To_Operator : String := "Thank you";
Record_Format : Tape_Tools.Record_Format :=
Tape_Tools.Fixed_Length;
Record_Length : Natural := 80;
Block_Length : Natural := 2000;
Response : Profile.Response_Profile := Profile.Get)
return Device is
function Mode_Name return String is
begin
case Mode is
when To_Tape =>
return "writing";
when From_Tape =>
return "reading";
end case;
end Mode_Name;
begin
Tape := Tape_Tools.Initialize (Format);
Log.Put_Line ("Connecting tape for " & Mode_Name,
Profile.Note_Msg, Response);
case Mode is
when To_Tape =>
Tape_Tools.Format (Tape,
Kind => Record_Format,
Record_Length => Record_Length,
Block_Length => Block_Length);
Tape_Tools.Connect_For_Output
(Tape, Vol_Id => Volume, To_Operator => To_Operator);
when From_Tape =>
Tape_Tools.Connect_For_Input
(Tape, Vol_Id => Volume, To_Operator => To_Operator);
end case;
Log.Put_Line ("Tape connected", Profile.Positive_Msg, Response);
return Tape;
exception
when others =>
Log.Put_Line ("Tape not connected", Profile.Negative_Msg, Response);
raise Tape_Error;
end Obtain;
procedure Release (Tape : Device;
Response : Profile.Response_Profile := Profile.Get) is
begin
begin
Tape_Tools.Disconnect (Tape);
exception
-- compensate for bug in vax/vms format handling of disconnect
when Io_Exceptions.Status_Error =>
if Tape_Tools."/=" (Tape_Tools.Status (Tape),
Tape_Tools.Other_Error) then
raise;
end if;
end;
Log.Put_Line ("Tape disconnected", Profile.Positive_Msg, Response);
exception
when others =>
Log.Put_Line ("Tape not disconnected",
Profile.Negative_Msg, Response);
raise Tape_Error;
end Release;
procedure Write (Tape : in out Device;
Host_Name, Tape_Name : String;
Record_Format : Tape_Tools.Record_Format :=
Tape_Tools.Fixed_Length;
Record_Length : Natural := 80;
Response : Profile.Response_Profile := Profile.Get) is
use Tape_Tools;
File : Io.File_Type;
Buffer_Length : constant Natural := 512;
Buffer : String (1 .. Buffer_Length);
Length : Natural := 0;
Line_Number : Natural := 0;
begin
begin
Io.Open (File => File, Name => Host_Name, Mode => Io.In_File);
exception
when others =>
Log.Put_Line ("Unable to open file => " & Host_Name,
Profile.Negative_Msg, Response);
return;
end;
Tape_Utils.Create (Tape, Tape_Name);
while not Io.End_Of_File (File) loop
Line_Number := Line_Number + 1;
Io.Get_Line (File, Item => Buffer, Last => Length);
if Record_Format = Tape_Tools.Fixed_Length then
if Length > Record_Length then
Log.Put_Line ("Line Number" & Natural'Image (Line_Number) &
" is too long!",
Profile.Negative_Msg, Response);
Log.Put_Line ("This line will be broken into two lines",
Profile.Negative_Msg);
Put_Line (Tape, Buffer (1 .. Record_Length));
Buffer (1 .. Length - Record_Length) :=
Buffer (Record_Length + 1 .. Length);
Buffer (Length - Record_Length + 1 .. Record_Length) :=
(others => ' ');
Put_Line (Tape, Buffer (1 .. Record_Length));
end if;
if Length < Record_Length then
Buffer (Length + 1 .. Record_Length) := (others => ' ');
Put_Line (Tape, Buffer (1 .. Record_Length));
end if;
else
Put_Line (Tape, Buffer (1 .. Length));
end if;
end loop;
Io.Close (File);
Tape_Tools.Close (Tape);
Log.Put_Line ("Wrote " & '"' & Host_Name & '"' &
" to " & '"' & Tape_Name & '"',
Profile.Positive_Msg, Response);
exception
when others =>
Log.Put_Line ("Failed to write " & '"' & Host_Name &
'"' & " to " & '"' & Tape_Name & '"',
Profile.Negative_Msg, Response);
raise Tape_Error;
end Write;
procedure Read (Tape : in out Device;
Host_Name : String := "";
Response : Profile.Response_Profile := Profile.Get) is
begin
Tape_Tools.Open (Tape);
declare
File : Io.File_Type;
File_Id : constant String := Tape_Tools.File_Id (Tape);
Buf_Size : constant Natural := Tape_Tools.Record_Length (Tape);
Buffer : String (1 .. Buf_Size);
Length : Natural;
function Local_File_Name return String is
begin
if Host_Name = "" then
return File_Id;
else
return Host_Name;
end if;
end Local_File_Name;
begin
Io.Create (File, Name => Local_File_Name);
while not Tape_Tools.End_Of_File (Tape) loop
Get_Line (Tape, Buffer, Length);
Io.Put_Line (File, Buffer (1 .. Length));
end loop;
Io.Close (File);
Log.Put_Line ("Read " & '"' & Local_File_Name & '"',
Profile.Positive_Msg, Response);
end;
Tape_Tools.Close (Tape);
exception
when others =>
Log.Put_Line ("Failed to read file",
Profile.Negative_Msg, Response);
raise Tape_Error;
end Read;
procedure Create (Tape : in out Device; Tape_Name : String) is
begin
Tape_Tools.Create (Tape, Id => Tape_Name);
end Create;
procedure Open (Tape : in out Device; Tape_Name : out String) is
begin
Tape_Tools.Open (Tape);
declare
File_Id : constant String := Tape_Tools.File_Id (Tape);
Last : constant Positive := Tape_Name'First + File_Id'Length - 1;
begin
Tape_Name (Tape_Name'First .. Last) := File_Id;
end;
end Open;
procedure Put_Line (Tape : Device; Line : String) is
begin
-- This is to compensate for a bug in the tape controller
-- where odd-length records are not handled properly.
if (Line'Length mod 2) = 0 then
Tape_Tools.Put_Line (Tape, Line);
else
Tape_Tools.Put_Line (Tape, Line & ' ');
end if;
end Put_Line;
end Tape_Utils;