Skip to content

Commit

Permalink
Add unchecked Bit_Array_To_Uint64, Pack pragma for bit array, working…
Browse files Browse the repository at this point in the history
… VARINT parsing!
  • Loading branch information
masonticehurst committed Feb 1, 2024
1 parent 85cc6c0 commit 11e7893
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 23 deletions.
22 changes: 10 additions & 12 deletions eRINA_STM32F7/src/net/cdap.adb
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package body CDAP is

procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Uint32) is
-- For setting VARINT fields
procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Uint64) is
Val_As_Uint32 : Uint32 := Uint32 (Val);
begin
case Field is
when Abs_Syntax =>
Self.Abs_Syntax := Val;
Self.Abs_Syntax := Val_As_Uint32;
when Invoke_Id =>
Self.Invoke_Id := Val;
Self.Invoke_Id := Val_As_Uint32;
when Result =>
Self.Result := Val;
Self.Result := Val_As_Uint32;
when Scope =>
Self.Scope := Val;
Self.Scope := Val_As_Uint32;
when Filter =>
Self.Filter := Val;
Self.Filter := Val_As_Uint32;
when Version =>
Self.Version := Val;
when others =>
-- MT: TODO: Should we make this throw an exception?
null;
Expand Down Expand Up @@ -48,10 +52,4 @@ package body CDAP is
begin
null;
end Set_Field;

procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Uint64)
is
begin
null;
end Set_Field;
end CDAP;
1 change: 0 additions & 1 deletion eRINA_STM32F7/src/net/cdap.ads
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ package CDAP is
Version : Uint64;
end record;

procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Uint32);
procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Op_Code);
procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : CDAPFlags);
procedure Set_Field (Self : in out CDAPMessage; Field : CDAP_Field; Val : Obj_Value);
Expand Down
32 changes: 22 additions & 10 deletions eRINA_STM32F7/src/net/protobuf.adb
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
-- This package exists to support Protobuf encoded
-- messages such as the CDAP ones coming from rLite
-- https://protobuf.dev/programming-guides/encoding/
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;

package body Protobuf is
use type Ada.Containers.Count_Type;

function Bit_Array_To_Uint64 is
new Ada.Unchecked_Conversion (Source => Bit_Array, Target => Uint64);

function Has_MSB (Input : Byte) return Boolean is
Result : constant Byte := input and 2#1000_0000#;
begin
return (Result = 1);
return (Result = 128);
end Has_MSB;

function Get_Bit_At (Input : Byte; Pos : Positive) return Bit is
function Get_Bit_At (Input : Byte; Pos : Natural) return Bit is
Shifted : constant Byte := Shift_Right(Input, Pos) and 2#0000_0001#;
begin
return Bit (Shifted);
Expand Down Expand Up @@ -42,13 +47,17 @@ package body Protobuf is
-- Drop most significant bit and shift right 3 times
Value : constant Byte := Shift_Right (Input and 2#0111_1111#, 3);
begin
-- MT: TODO: Debug only! Remove Me!
Put_Line ("Decoded tagged field :: " & CDAP_Field'Enum_Val (Value)'Image);

-- MT: TODO: Need to handle weird case when resulting value does not match an enum in CDAP_Field
return CDAP_Field'Val (Value);
return CDAP_Field'Enum_Val (Value);
end Tag_To_Field_Number;

function To_VARINT (V : in Byte_Vector) return Uint64 is
Working_Byte_Vector : Byte_Vector;
Working_Bit_Array : Bit_Array(1 .. 64) := (others => 0);
Result : Uint64 := 0;

procedure Remove_MSB (C : Byte_Cursor) is
MSB_Removed : constant Byte := V (C) and 2#0111_1111#;
Expand All @@ -69,19 +78,22 @@ package body Protobuf is
end if;

-- Flip endianness and drop the MSB of each byte
-- The MSB is just there to tell us whether weve reached the end of the number
V.Reverse_Iterate (Process => Remove_MSB'Access);
-- The MSB is just there to tell us whether we've reached the end of the number
-- V.Reverse_Iterate (Process => Remove_MSB'Access);

-- For each byte
for I in V.First_Index .. V.Last_Index loop
-- For each bit in this byte
for J in 1 .. 8 loop
Working_Bit_Array((I - V.First_Index) * 8 + J) := Get_Bit_At (V(I), J - 1);
-- For each bit in this byte, note 1 .. 7 and not 1 .. 8, we ignore the MSB
for J in 1 .. 7 loop
Working_Bit_Array((I - V.First_Index) * 7 + J) := Get_Bit_At (V(I), J - 1);
end loop;
end loop;

-- MT: TODO: Debug only! Remove Me!
Put_Line ("Decoded VARINT to be :: " & Uint64'Image(Bit_Array_To_Uint64 (Working_Bit_Array)));

-- TODO: MT Concatenate bytes and unchecked cast to uint64
return 0;
-- MT: TODO: May need some idiot proofing
return Bit_Array_To_Uint64 (Working_Bit_Array);
end To_VARINT;

function To_CDAP(V : in Byte_Vector) return CDAPMessage is
Expand Down
1 change: 1 addition & 0 deletions eRINA_STM32F7/src/net/protobuf.ads
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ package Protobuf is

type Bit is range 0 .. 1 with Size => 1;
type Bit_Array is array (Positive range <>) of Bit;
pragma Pack (Bit_Array);

-- Takes in a vector of bytes and returns a CDAP message record
function To_CDAP(V : in Byte_Vector) return CDAPMessage;
Expand Down

0 comments on commit 11e7893

Please sign in to comment.