Стивенс Уильям Ричард
Шрифт:
8-9 Макрос RNDUP определен в файле <rpc/xdr.h>. Он округляет аргумент к ближайшему кратному BYTES_PER_XDR_UNIT (4). Для массива фиксированного размера вычисляется размер каждого элемента, который затем умножается на количество элементов.
Проблема возникает в случае использования типов данных переменной длины. Если мы объявим stringd<10>, максимальный размер будет RNDUP(sizeof( int)) (для длины) плюс RNDUP(sizeof(char)*10) (для символов строки). Но мы не можем вычислить размер буфера, если максимальный размер не указан в объявлении переменной (например, float e<>). Лучше всего в этом случае выделять буфер с запасом, а потом проверять, не возвращают ли подпрограммы XDR ошибку (упражнение 16.5).
Пример: необязательные данные
Существуют три способа задания необязательных данных в файле XDR, примеры для всех приведены в листинге 16.17.
1-8 Мы определяем объединение с ветвями FALSE и TRUE и структуру этого типа. Если флаг дискриминанта TRUE, за ним следует значение типа long; в противном случае за ним ничего не следует. После кодирования библиотекой XDR это объединение будет закодировано как:
■ 4 байта флага со значением 1 (TRUE) и 4 байта целочисленного значения либо
■ 4 байта флага со значением 0 (FALSE).
9 Если мы указываем массив переменной длины с одним возможным элементом, он будет передан как:
■ 4 байта со значением 1 и 4 байта значения либо
■ 4 байта со значением 0.
10 Новый способ определения необязательных данных заключается в объявлении указателя. Он будет закодирован как:
■ 4 байта со значением 1 и 4 байта значения либо
■ 4 байта со значением 0
в зависимости от значения соответствующего указателя при кодировании данных. Если указатель ненулевой, используется первый вариант кодирования. Если указатель нулевой, получится второй вариант. Это удобный способ кодирования необязательных данных в случае, если в нашем коде имеется указатель на эти данные.
Важная деталь реализации, благодаря которой оба варианта дают одинаковый результат при кодировании, заключается в том, что значение TRUE равно 1, что совпадает с длиной массива переменной длины, когда в нем есть один элемент.
В листинге 16.18 приведен текст заголовочного файла, созданного программой rpcgen для данного файла спецификации.
14-21 Хотя все три аргумента кодируются одинаково, способы присваивания и получения их значений в языке С различны.
В листинге 16.19 приведен текст простой пpoгрaммы, устанавливающей значения всех трех аргументов так, что ни одно из полей long не кодируется.