Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

34 printf("uarg (int) = %d\n", in.uarg.union_arg_u.intval);

35 break;

36 case RESULT_DOUBLE:

37 printf("uarg (double) = %g\n", in.uarg.union_arg_u.doubleval);

38 break;

39 default:

40 printf("uarg (void)\n");

41 break;

42 }

43 xdr_free(xdr_data, (char*)&in);

44 exit(0);

45 }

Выделение правильно расположенного буфера

11-13 Вызывается функция malloc для выделения буфера. В этот буфер считывается файл, созданный предыдущей программой.

Создание потока XDR, инициализация буфера, декодирование

14-17 Инициализируем поток XDR, указав флаг XDR_DECODE, означающий, что преобразование производится из формата XDR в формат узла. Мы инициализируем структуру i n нулями и вызываем xdr_data для декодирования содержимого буфера buff в эту структуру. Мы обязаны инициализировать принимающую структуру нулями, поскольку некоторые из подпрограмм XDR (например, xdr_string) требуют выполнения этого условия. xdr_data — это та же функция, которую мы вызывали в листинге 16.13. Изменился только последний аргумент xdrmem_create: в предыдущей программе мы указывали XDR_ENCODE, а в этой — XDR_DECODE. Это значение сохраняется в дескрипторе XDR (xhandle) функцией xdrmem_create и затем используется библиотекой XDR для выбора между кодированием и декодированием данных.

Вывод значений полей структуры

18-42 Мы выводим значения всех полей структуры data.

Освобождение выделенной под XDR памяти

43 Для освобождения памяти мы вызываем функцию xdr_free (см. упражнение 16.10).

Запустим программу write на компьютере Sparc, перенаправив стандартный вывод в файл с именем data:

solaris % write > data

solaris % ls -l data

– rw-rw-r-- 1 rstevens other1 76 Apr 23 12:32 data

Мы видим, что размер файла равен 72 байтам что соответствует рис. 16.4, на котором изображена схема хранения данных.

Прочитав этот файл в BSD/OS или Digital Unix, мы получим те результаты, на которые и рассчитывали:

bsdi % read < data

read 76 bytes

short_arg = 1, long_arg = 2, vstring_arg = 'hello, world'

fopaque[] =99, 88, 77

vopaque<> = 33 44

fshort_arg[] = 9999, 8888, 7777, 6666

vlong<> = 123456 234567 345678

uarg (int) = 123

alpha % read < data

read 76 bytes

short_arg = 1, long_arg = 2, vstring_arg = 'hello, world'

fopaque[] = 99, 88, 77

vopaque<> = 33 44

fshort_arg[] = 9999, 8888, 7777, 6666

vlong<> = 123456 234567 345678

uarg (int) = 123

Рис. 16.4. Формат потока XDR, записанный в листинге 16.13

Пример: вычисление размера буфера

В предыдущем примере мы выделяли буфер размера BUFFSIZE (определенного в файле unpiрс.h в листинге В.1), и этого было достаточно. К сожалению, не существует простого способа вычислить объем памяти, нужный XDR для кодирования конкретных данных. Вычислить размер структуры вызовом sizeof недостаточно, потому что каждое поле кодируется XDR по отдельности. Нам придется перебирать элементы структуры, прибавляя к конечному результату объем памяти, нужный XDR для кодирования очередного элемента. В листинге 16.15 приведен пример простой структуры с тремя полями.

Листинг 16.15. Спецификация XDR для простой структуры

//sunrpc/xdrl/examplе.х

1 const MAXC = 4;

2 struct example {

3 short a;

4 double b;

5 short c[MAXC];

6 };

Программа, текст которой приведен в листинге 16.16, вычисляет размер буфера, требуемого XDR для кодирования этой структуры. Он получается равным 28 байт.

Листинг 16.16. Программа, вычисляющая размер буфера XDR

//sunrpc/xdr1/example.c

1 #include "unpipc.h"

2 #include "example.h"

3 int

4 main(int argc, char **argv)

5 {

6 int size;

7 example foo;

8 size = RNDUP(sizeof(foo.a)) + RNDUP(sizeof(foo.b)) +

9 RNDUP(sizeof(foo.c[0])) * MAXC;

10 printf("size = %d\n", size);

11 exit(0);

12 }

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.

Листинг 16.17. Файл спецификации XDR, иллюстрирующий способы задания необязательных данных

//sunrpc/xdr1/opt1.x

1 union optlong switch (bool flag) {

2 case TRUE:

3 long val;

4 case FALSE:

5 void;

Поделиться:
Популярные книги

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней

Кукловод

Майерс Александр
4. Династия
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кукловод

#Бояръ-Аниме. Газлайтер. Том 24

Володин Григорий Григорьевич
24. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 24

Снега

Чепурин Юлий Петрович
Поэзия:
драматургия
5.00
рейтинг книги
Снега

Матабар III

Клеванский Кирилл Сергеевич
3. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар III

Я все еще царь. Книга XXXI

Дрейк Сириус
31. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я все еще царь. Книга XXXI

Базис

Владимиров Денис
7. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Базис

Я еще не бог. Книга XXXV

Дрейк Сириус
35. Дорогой барон!
Фантастика:
аниме
попаданцы
5.00
рейтинг книги
Я еще не бог. Книга XXXV

Вторая жизнь майора. Цикл

Сухинин Владимир Александрович
Вторая жизнь майора
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Вторая жизнь майора. Цикл

Гранд

Демченко Антон Витальевич
3. Воздушный стрелок
Фантастика:
боевая фантастика
8.12
рейтинг книги
Гранд

Идеальный мир для Лекаря 23

Сапфир Олег
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 23

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Страж Кодекса. Книга V

Романов Илья Николаевич
5. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга V

На границе империй. Том 8

INDIGO
12. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8