From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bd39486c8814dbfc,start X-Google-Attributes: gid103376,public From: Doug Rogers Subject: Problem to dramatize packed-array/rep-clause difficulties (long) Date: 1996/03/27 Message-ID: <4jankp$30h@ra.nrl.navy.mil> X-Deja-AN: 144416213 content-type: text/plain; charset=us-ascii organization: Naval Research Laboratory x-url: news:comp.lang.ada?ALL mime-version: 1.0 newsgroups: comp.lang.ada x-mailer: Mozilla 1.1N (X11; I; Linux 1.3.69 i486) Date: 1996-03-27T00:00:00+00:00 List-Id: In lieu of more discussion of the difficulties of doing low-level bit access and binary file i/o in Ada83, I'm posting a little, much-simplified problem for the Ada community at large. I'm honestly stumped on this one. I've tried countless ways (ok, aleph-naught ways!) to solve the problem elegantly. For the most elegant solution completely coded in Ada83 (you may use the DEC standard Sequential_Mixed_IO package, as described below), I offer as a prize... um... a heartfelt "Thanks!". Sorry, that's all I can afford (unless you live in the Washington DC or Colorado Springs CO area, in which case I'll take you out to lunch). Without further ado, I begin: Suppose your job is to read in a stream of data (hey, that's MY job, too!), and that data represents analog to digital convertor values from some sensors. Each sensor runs in two modes: low resolution, producing 12 samples of 6-bit values, and high resolution, producing 8 samples of 9-bit values. Assume the data comes from a binary file. The first record in the file is the header. It contains a 12-bit sensor count and a four-bit timetag. Each sensor contains a list of sensor data, whose format varies according to the mode bit (Mod). When Mod is set to 0, low precision data is present. When 1, high precision data is present. For convenience, assume you have a byte-addressable machine with a 32-bit wordsize. Note that I'm being pretty nice about all the boundaries except the arrays. Okay, here's the format to be supported: bytes _7_._6_._5_._4_._3_._2_._1_._0_ lsb (intel order) Header => 0 |---------sensor count--------->| 1 |<--time tag--->|<---(cont'd)---| A sensor record follows for each sensor count. bytes _7_._6_._5_._4_._3_._2_._1_._0_ lsb (intel order) Sensor => 0 |<-------unused bits------->|Mod| (Data) 1 .. 9 | sensor data, according to Mod | see below case Mod is when 0 => -- low resolution, 12 samples of 6-bit values bytes _7_._6_._5_._4_._3_._2_._1_._0_ lsb (intel order) Low => 0 |-(#1)->|<-------low #0-------->| Res 1 |----low #2---->|<----low #1----| Data 2 |<-------low #3-------->|<-(#2)-| 3 |-(#5)->|<-------low #4-------->| 4 |----low #6---->|<----low #5----| 5 |<-------low #7-------->|<-(#6)-| 6 |-(#9)->|<-------low #8-------->| 7 |----low #10--->|<----low #9----| 8 |<-------low #11------->|<-(10)-| when 1 => -- high resolution, 8 samples of 12-bit values bytes _7_._6_._5_._4_._3_._2_._1_._0_ lsb (intel order) Data => 0 |---------hi res #0------------>| 1 |---------hi res #1-------->|<--| 2 |---------hi res #2---->|<-(#1)-| 3 |----hi res #3----->|<---(#2)---| 4 |------(#4)---->|<------(#3)----| 5 |---(#5)--->|<----hi res #4-----| 6 |-(#6)->|<--------hi res #5-----| 7 |-->|<--------hi res #6---------| 8 |<------------hi res #7---------| end case; Your mission, should you choose to accept it, is to read in a file with a header (just one per file is ok) and at least 2 of each type of sensor record. Then print out the contents using Text_IO/.Integer_IO. All this must be done in Ada83 (Ada95 solutions welcome, too, but I can not use them *sigh*). The difficulty is getting around the packed arrays of 6-bit and 9-bit values. Here's my dream-world solution: Natural_Language.Esperanto.Execute ("montru sensilajn datumojn."); Just kidding. Here's my if-Ada-honored-representations-as-well-as-the- language-allows-them-to-be-specified solution: --------[start "show_sensor_data.adb"]------------------------------------ -- Please excuse any shortcuts. It's late, and it's only an example. -- with Sequential_Mixed_IO; -- DEC standard mixed-IO package providing -- generic gets/puts to/from a file for -- differently-typed data elements. -- Further discussion below. with Text_IO; use Text_IO; procedure Dump_Sensor_Data is package Int_IO is new Integer_IO (Natural); use Int_IO; subtype Natural12 is Natural range 0 .. (2 ** 12) - 1; for Natural12'size use 12; subtype Natural9 is Natural range 0 .. (2 ** 9) - 1; for Natural9'size use 9; subtype Natural7 is Natural range 0 .. (2 ** 7) - 1; for Natural7'size use 7; subtype Natural6 is Natural range 0 .. (2 ** 6) - 1; for Natural6'size use 6; subtype Natural4 is Natural range 0 .. (2 ** 4) - 1; for Natural4'size use 4; type Resolutions is (Low, High); for Resolutions use (Low => 0, High => 1); for Resolutions'size use 1; type Headers is record Sensor_Count : Natural12; Time_Tag : Natural4 end record; for Headers use record Sensor_Count at 0 range 0 .. 11; Time_Tag at 0 range 12 .. 15; end record; -- -- !!!! Here's the tricky stuff !!!! -- type Low_Res_Data is array (Natural range 0 .. 11) of Natural6; pragma Pack (Low_Res_Data); -- right! type High_Res_Data is array (Natural range 0 .. 7) of Natural9; pragma Pack (High_Res_Data); -- now I'm really dreaming! type Sensor_Data (Mode : Resolutions := Low) is record Unused : Natural7; case Mode is when Low => Low_Res : Low_Res_Data; when High => High_Res : High_Res_Data; end case; end record; for Sensor_Data use record Mode at 0 range 0 .. 0; Unused at 0 range 1 .. 7; Low_Res at 1 range 0 .. 71; High_Res at 1 range 0 .. 71; end record; -- -- The following are instances of: -- package Sequential_Mixed_IO is -- ... -- generic -- type Element_Type is private; -- procedure Get -- (File : in File_Type; -- Item : out Element_Type); -- The standard exceptions and Open/Close procedures are provided, too. -- procedure Get_Header is new Sequential_Mixed_IO.Get (Headers); procedure Get_Sensor_Data is new Sequential_Mixed_IO.Get (Sensor_Data); procedure Put (H : in Headers) is begin -- Put Put ("Number of sensor records => "); Put (Natural (H.Sensor_Count), Width => 1); New_Line; Put ("Time tag => "); Put (Natural (H.Time_Tag), Width => 1); New_Line; end Put; procedure Put (S : in Sensor_Data) is begin -- Put Put ("Sensor mode => "); Put (Resolutions'image (S.Mode)); New_Line; case S.Mode is when Low => for Index in Low_Res_Data'range loop Put (" Data ("); Put (Natural (Index), Width => 1); Put (") => "); Put (Natural (S.Low_Res (Index))); New_Line; end loop; when High => for Index in High_Res_Data'range loop Put (" Data ("); Put (Natural (Index), Width => 1); Put (") => "); Put (Natural (S.High_Res (Index))); New_Line; end loop; end case; end Put; Header : Headers; Data : Sensor_Data; File : Sequential_Mixed_IO.File_Type; begin -- Show_Sensor_Data Put_Line ("============================================================"); Sequential_Mixed_IO.Open (File, "sensor.dat"); Get_Header (File, Item => Header); Put (Header); for Index in Natural12 range 1 .. Header.Sensor_Count loop Put ("Loading data for sensor #"); Put (Natural (Index), Width => 1); New_Line; Get_Sensor_Data (File, Item => Data); Put (Data); end loop; Sequential_Mixed_IO.Close (File); Put_Line ("Done."); end Show_Sensor_Data; --------[end "show_sensor_data.adb"]-------------------------------------- Wouldn't that be nice? Doug =------cxiuj-opinioj-estas-sole-miaj.-----any-opinions-are-mine-alone.------= = Doug Rogers vocxe/voice = 1.703.893.2007 fakse/fax = 1.703.893.5890 = = Innovative Concepts Inc; 8200 Greensboro Drive Suite 801; McLean VA 22102 = = PGP ID: pub 1024/016DE91D 1994/11/14 Doug Rogers = =senemankasalvimultodatempolernulaanglan-ifyouvegotalittletimelearnesperanto=