Без использования нестандартного предложения ‡ Scalar_Storage_Order в последних выпусках GNAT, как, скажем, заголовок IPv4 может быть переносимым образом представлен через предложение (я) представления записи в сочетании с любой комбинацией любых других языковых функцийтак, чтобы «один и тот же» код работал как на процессорах с прямым порядком байтов, так и на процессорах с прямым порядком байтов, но передавался по проводам (например, через, скажем, полезную нагрузку кадра Ethernet) в том, что IETF называет сетевым байтовым порядком (то есть IETFпричудливое название для big-endian).В C «тот же» код может использовать макросы препроцессора для выполнения замены байтов на процессорах с прямым порядком байтов, но не должен использоваться на процессорах с прямым порядком байтов, но стандартный Ada не имеет препроцессора.В C ++ «тот же» код может использовать мета-шаблонное программирование (MTP) для выполнения перестановки байтов на процессорах с прямым порядком байтов, но не должен использоваться на процессорах с прямым порядком байтов, но в стандартном Ada отсутствует MTP.
(Кстати, почти такая же проблема возникает в драйвере устройства, когда процессор с прямым порядком байтов взаимодействует с регистром отображения памяти периферийной ИС с прямым порядком байтов или наоборот: процессор с прямым порядком байтов взаимодействует с памятью ИС с прямым порядком байтов.сопоставленный регистр.)
BytesPerWord : constant := 4;
BitsPerByte : constant := 8;
PowerOf2Highest : constant := BytesPerWord*BitsPerByte - 1; -- part #1 of byte-swap
type Header_IPv4 is record
Version : integer range 0 .. F#16;
IHL : integer range 0 .. F#16;
TOS : integer range 0 .. FF#16;
Length : integer range 0 .. FF#16;
Ident : integer range 0 .. FFFF#16;
Flags : integer range 0 .. 7#16;
Frag_Offs : integer range 0 .. 1FFF#16;
end record;
type Header_IPv4_Homogenous is new Header_IPv4;
for Header_IPv4_Homogenous use record -- Good-to-go for big-endian processors
Version at 0*BytesPerWord range 0 .. 3;
IHL at 0*BytesPerWord range 4 .. 7;
TOS at 0*BytesPerWord range 8 .. 15;
Length at 0*BytesPerWord range 16 .. 31;
Ident at 1*BytesPerWord range 0 .. 15;
Flags at 1*BytesPerWord range 16 .. 18;
Frag_Offs at 1*BytesPerWord range 19 .. 31;
end record;
for Header_IPv4_Homogenous'Alignment use 4;
for Header_IPv4_Homogenous'Bit_Order use High_Order_First;
type Header_IPv4_Heterogenous is new Header_IPv4;
for Header_IPv4_Heterogenous use record -- Good-to-go??? for little-endian processors?
Version at 0*BytesPerWord range PowerOf2Highest- 3 .. PowerOf2Highest- 0; -- p
IHL at 0*BytesPerWord range PowerOf2Highest- 7 .. PowerOf2Highest- 4; -- a
TOS at 0*BytesPerWord range PowerOf2Highest- 15 .. PowerOf2Highest- 8; -- r
Length at 0*BytesPerWord range PowerOf2Highest- 31 .. PowerOf2Highest- 16; -- t
Ident at 1*BytesPerWord range PowerOf2Highest- 15 .. PowerOf2Highest- 0; --
Flags at 1*BytesPerWord range PowerOf2Highest- 18 .. PowerOf2Highest- 16; -- #
Frag_Offs at 1*BytesPerWord range PowerOf2Highest- 31 .. PowerOf2Highest- 19; -- 2
end record;
for Header_IPv4_Heterogenous'Alignment use 4;
for Header_IPv4_Heterogenous'Bit_Order use Low_Order_First; -- part #3 of byte-swap
Обратите внимание на то, как «PowerOf2Highest минус» и «инвертирует» битовые идентификаторы с прямым порядком байтов от (от, к) к порядку [визуально, арифметически не реально] (к, от)используются во второй части байт-свопа в качестве грубого эквивалента спада VHDL, который является ключевой частью того, как VHDL решит эту проблему гетерогенной последовательности.(VHDL является родственным языком для Ada83.)
Но теперь, как скрыть, какой член набора {Header_IPv4_Homogenous, Header_IPv4_Heterogenous} был выбран в качестве имени типа Header_IPv4_Portable в app-domain-code?Использовать дочерние пакеты?
‡ Scalar_Storage_Order было предложено в качестве потенциальной функции для следующего издания стандарта ISO Ada, но пока что нет официального спонсора, выступающего за предложение в ISOкомитет по стандартизации, так что предложение по стандартизации может куда-то уйти и умереть на корню.Кроме того, я буду использовать не-GNAT-компилятор Ada, поэтому использование функции, специфичной для GNAT, для меня недоступно.