title: Extracting record from big endian data
body: <p>I have the following code for network protocol implementation. As the protocol is big endian, I wanted to use the <em>Bit_Order</em> attribute and <em>High_Order_First</em> value but it seems I made a mistake.</p>
  
  <pre class="lang-ada prettyprint-override"><code>With Ada.Unchecked_Conversion;
  with Ada.Text_IO; use Ada.Text_IO;
  with System; use System;
  
  procedure Bit_Extraction is
  
     type Byte is range 0 .. (2**8)-1 with Size =&gt; 8;
  
     type Command is (Read_Coils,
                      Read_Discrete_Inputs
                     ) with Size =&gt; 7;
  
     for Command use (Read_Coils =&gt; 1,
                      Read_Discrete_Inputs =&gt; 4);
  
     type has_exception is new Boolean with Size =&gt; 1;
  
      type Frame is record
        Function_Code : Command;
        Is_Exception : has_exception := False;
     end record
       with Pack =&gt; True,
       Size =&gt; 8;
  
     for Frame use
        record
           Function_Code at 0 range 0 .. 6;
           Is_Exception at 0 range 7 .. 7;
        end record;
  
     for Frame'Bit_Order use High_Order_First;
     for Frame'Scalar_Storage_Order use High_Order_First;
  
     function To_Frame is new Ada.Unchecked_Conversion (Byte, Frame);
  
     my_frame : Frame;
  begin
     my_frame := To_Frame (Byte'(16#32#)); -- Big endian version of 16#4#
     Put_Line (Command'Image (my_frame.Function_Code)
               &amp; " "
               &amp; has_exception'Image (my_frame.Is_Exception));
  end Bit_Extraction;
  </code></pre>
  
  <p>Compilation is ok but the result is</p>
  
  <pre><code>raised CONSTRAINT_ERROR : bit_extraction.adb:39 invalid data
  </code></pre>
  
  <p>What did I forget or misunderstand ?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>The real record in fact is </p>
  
  <pre class="lang-ada prettyprint-override"><code>type Frame is record
        Transaction_Id : Transaction_Identifier;
        Protocol_Id : Word := 0;
        Frame_Length : Length;
        Unit_Id : Unit_Identifier;
        Function_Code : Command;
        Is_Exception : Boolean := False;    
  end record with Size =&gt; 8 * 8, Pack =&gt; True;
  
  for Frame use
        record
           Transaction_Id at 0 range 0 .. 15;
           Protocol_Id at 2 range 0 .. 15;
           Frame_Length at 4 range 0 .. 15;
           Unit_id at 6 range 0 .. 7;
           Function_Code at 7 range 0 .. 6;
           Is_Exception at 7 range 7 .. 7;
        end record;
  </code></pre>
  
  <p>Where <em>Transaction_Identifier</em>, <em>Word</em> and <em>Length</em> are 16-bit wide.</p>
  
  <p>These ones are displayed correctly if I remove the <em>Is_Exception</em> field and extend <em>Function_Code</em> to 8 bits.</p>
  
  <p>The dump of the frame to decode is as following:</p>
  
  <pre><code>00000000  00 01 00 00 00 09 11 03  06 02 2b 00 64 00 7f
  </code></pre>
  
  <p>So my only problem is really to extract the 8th bit of the last byte.</p>