How do I read a binary file in BigEndian order to a record?
21 August 2023 at 17:36
I have a binary file format that is written in BigEndian order. The files are of varying size so I can't use Sequential_IO for this, as I need to read different types.
The problem is, when using Stream_IO, I can't find a way to use BigEndian, and Scalar_Storage_Order also doesn't affect anything. Also, I'm a very fresh beginner at Ada and overall tips and suggestions to the code are very welcome.
share.adb:
with Ada.Text_IO;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Streams; use Ada.Streams;
package body Share is
procedure Read_Share (Segment_Size : Positive; Required_Shares : Positive)
is
-- Ceiling function
Block_Size : constant Positive :=
(Segment_Size + (Required_Shares - 1)) / Required_Shares;
type Block is array (Integer range 0 .. Block_Size) of Byte;
S : Stream_Access;
Share_File : File_Type;
My_Share_Header : Share_Header;
begin
Open (Share_File, In_File, "../go-tahoe/3");
S := Stream (Share_File);
Share_Header'Read (S, My_Share_Header);
My_Share_Header.Block_Size := Unsigned_32 (Block_Size);
Display_Share_Content (My_Share_Header);
Close (Share_File);
-- Read_Blocks (My_Share_Header, Share_File);
-- Now My_Share contains the values read from the binary file
end Read_Share;
procedure Display_Share_Content (My_Share_Header : Share_Header) is
begin
Ada.Text_IO.Put_Line
("Share version: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Version));
Ada.Text_IO.Put_Line
("Share Data Length: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Data_Length));
Ada.Text_IO.Put_Line
("Lease Number: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Lease_number));
Ada.Text_IO.Put_Line
("Share version: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Version));
Ada.Text_IO.Put_Line
("Block Size: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Block_Size));
Ada.Text_IO.Put_Line
("Data Size: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Data_Size));
Ada.Text_IO.Put_Line
("Data offset: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Data_Offset));
Ada.Text_IO.Put_Line
("Plaintext hash tree offset: " &
Interfaces.Unsigned_32'Image
(My_Share_Header.Plaintext_Hash_Tree_Offset));
Ada.Text_IO.Put_Line
("Crypttext hash tree offset: " &
Interfaces.Unsigned_32'Image
(My_Share_Header.Crypttext_Hash_Tree_Offset));
Ada.Text_IO.Put_Line
("Block hashes offset: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Block_Hashes_Offset));
Ada.Text_IO.Put_Line
("Share hashes offset: " &
Interfaces.Unsigned_32'Image (My_Share_Header.Share_Hashes_Offset));
Ada.Text_IO.Put_Line
("URI Extension Length and URI Extension block offset: " &
Interfaces.Unsigned_32'Image (My_Share_Header.URI_Extension_Offset));
end Display_Share_Content;
procedure Read_Blocks
(My_Share_Header : Share_Header; Share_File : File_Type)
is
Total_Blocks : Interfaces.Unsigned_32 := My_Share_Header.Data_Size;
begin
Ada.Text_IO.Put ("");
end Read_Blocks;
end Share;
share.ads:
with Interfaces; use Interfaces;
with System; use System;
with Ada.Streams.Stream_IO;
package Share is
type Byte is new Interfaces.Unsigned_8;
type Kilobyte is array (Integer range 0 .. 1_023) of Byte;
type Kilobyte_array is array (Integer range <>) of Kilobyte;
type Share_Header is record
Version : Unsigned_32;
Data_Length : Unsigned_32;
Lease_number : Unsigned_32;
Version_Junk : Unsigned_32;
-- unused as it can be calculated from the URI
Block_Size : Unsigned_32;
Data_Size : Unsigned_32;
Data_Offset : Unsigned_32;
Plaintext_Hash_Tree_Offset : Unsigned_32;
Crypttext_Hash_Tree_Offset : Unsigned_32;
Block_Hashes_Offset : Unsigned_32;
Share_Hashes_Offset : Unsigned_32;
URI_Extension_Offset : Unsigned_32;
end record;
for Share_Header use record
Version at 0 range 0 .. 32;
-- Data_Length : Unsigned_32;
-- Lease_number : Unsigned_32;
-- Version_Junk : Unsigned_32;
-- -- unused as it can be calculated from the URI
-- Block_Size : Unsigned_32;
-- Data_Size : Unsigned_32;
-- Data_Offset : Unsigned_32;
-- Plaintext_Hash_Tree_Offset : Unsigned_32;
-- Crypttext_Hash_Tree_Offset : Unsigned_32;
-- Block_Hashes_Offset : Unsigned_32;
-- Share_Hashes_Offset : Unsigned_32;
-- URI_Extension_Offset : Unsigned_32;
end record;
for Share_Header'Bit_Order use High_Order_First;
for Share_Header'Scalar_Storage_Order use High_Order_First;
procedure Read_Share (Segment_Size : Positive; Required_Shares : Positive);
procedure Display_Share_Content (My_Share_Header : Share_Header);
procedure Read_Blocks
(My_Share_Header : Share_Header;
Share_File : Ada.Streams.Stream_IO.File_Type);
end Share;
Tried defining the component clauses to not much success, different bit orders, modifying the Stream_IO storage arrays.