From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 3 Jan 93 05:06:00 GMT From: att!fang!tarpit!cs.ucf.edu!crigler@ucbvax.Berkeley.EDU (James Crigler) Subject: Re: Can this data be represented in Ada? Message-ID: List-Id: psm@nosc.mil (Scot Mcintosh) writes: >I'm implementing a data communications protocol that has some data >structural features that don't look possible to implement in Ada. >Perhaps someone more experienced can suggest a way to accomplish >what I'm trying to do (changing the protocol is not an option). >A Transmission Unit looks like: [Picture deleted] >Each Packet looks like: [Picture deleted] >For a given transmission, the Packet Length is fixed, but can be >different in the next transmission. The Data Length within each >Packet can be different for each Packet. I've tried to figure out how >to define Ada types for the Transmission Unit and Packet that >allow for the variability of the field sizes and haven't succeeded. >Any ideas? Thanks in advance. I've done this kind of thing before, and it's not easy to map this kind of structure at compile time: Ada just won't let you do it. However, it may be possible to create your structure at run time by use of blocks contained in procedures. Below is a little idea. I've filled in some stuff by assumption. procedure CREATE_TRANSMISSION (PACKET_SIZE : in POSITIVE, [other parms as required]) is subtype PACKET_LENGTH is POSITIVE range 1 .. 255; -- or whatever subtype DATUM is NATURAL range 0 .. 255; -- or whatever type PACKET_DATA is array (1 .. PACKET_SIZE - 1) of DATUM; type PACKET is record DATA_SIZE : POSITIVE; DATA : PACKET_DATA; end record; TRANSIMISSION_UNIT_SIZE : constant := 1024; PACKET_COUNT : constant := TRANSMISSION_UNIT_SIZE / PACKET_SIZE; -- But if it can be an even multiple, subtract 1. type TRANSMISSION_UNIT is record PACKET_SIZE : PACKET_LENGTH; PACKET : array (1 .. PACKET_COUNT) of PACKET; end record; -- Put necessary procedures to fill in data here, followed by -- main body of procedure. At the receiving end, use a system like this: with SYSTEM; package body FRED is subtype PACKET_LENGTH is POSITIVE range 1 .. 255; -- or whatever subtype DATUM is NATURAL range 0 .. 255; -- or whatever TRANSIMISSION_UNIT_SIZE : constant := 1024; type RECEPTION_UNIT is record PACKET_SIZE : PACKET_LENGTH; DATA : ARRAY (1 .. TRANMISSION_UNIT_SIZE - 1) of DATUM; end record; procedure DECODE_DATA (DATA : in RECEPTION_UNIT) is type PACKET_DATA is array (1 .. DATA.PACKET_SIZE - 1) of DATUM; type PACKET_REC is record DATA_SIZE : PACKET_LENGTH; DATA : PACKET_DATA; end record; PACKET_COUNT : constant := TRANSMISSION_UNIT_SIZE / DATA.PACKET_SIZE; -- But if it can be an even multiple, subtract 1. type PACKET_ARRAY is array (1 .. PACKET_COUNT) of PACKET_REC; PACKET : PACKET_ARRAY; for PACKET use at DATA.DATA'ADDRESS; [other declarations and procedure body] I haven't used anything like this in a long time but I think it should work. The trick here is that the in mode parameter PACKET_SIZE is a constant at run time from the procedure's point of view. There are two problems: 1. A hit in run time if there is a lot of range checking to do. Remember that the language is required to do a lot of "safety" checking behind your back, so you may have to program to defend yourself against the language. 2. You don't get a global "type" that you can put in a package spec for the world to see. Hope this sheds a little lux et veritas. Jim Crigler ------------------------------------------------------ !PC