2012-04-10 3 views
2

Я пишу функции, которые берут контрольную сумму двух разных вещей: один, файл; и два, запись в архиве a la библиотека библиотеки BSD libarchive. Я заимствовал код контрольной суммы из GNU's coreutils.C: пример дублирования кода

Мой код делает контрольную сумму файла считывает из своего источника, как это:

unsigned char buf[BUFLEN]; 
size_t bytes_read; 
FILE *fp; 
... 
while ((bytes_read = fread (buf, 1, BUFLEN, fp)) > 0) { ... } 

В моем коде для чтения из записи архива, соответствующий код выглядит

struct archive *ar; 
unsigned char buf[BUFLEN]; 
ssize_t bytes_read; 
... 
while ((bytes_read = archive_read_data(ar, buf, sizeof(buf))) > 0) { ... } 

As он стоит, у меня должно быть две разные функции, хотя большая часть кода такая же. Я не совсем понимаю, как это сделать, передав указатель на функцию, так как fread и archive_read_data даже не имеют одинакового количества аргументов. (Я думаю, я мог бы начать с использования read (2) вместо fread (3), но я не уверен, что это эффективный способ продолжить.)

Есть ли хороший способ избежать дублирования кода здесь? Помимо попыток сделать это с помощью указателей функций, я мог бы сделать это, поставив одинаковые фрагменты кода в отдельные файлы, затем #including 'их, но это кажется уродливым.

В этом конкретном примере код функций не так уж и длинный, поэтому просто идти вперед и дублировать код не так уж и важно. Мне просто интересно, существует ли элегантное решение.

ответ

2

Вы можете создать свои собственные функции обертки для fread() и archive_read_data(), которые имеют идентичные прототипы. Каждая из этих оболочек будет содержать только одну строку кода, чтобы вызвать базовую функцию read(), переставляя параметры по мере необходимости.

Затем используйте указатель на функцию, чтобы различать ваши две обертки в зависимости от контекста.

0

Обе функции действительно нужны только 3 арг:

  • указатель на источник данных
  • указатель на буфер данных
  • количество байт для чтения

Вы можете написать обертку для fread, чтобы получить такую ​​же подпись, как archive_read_data (или наоборот):

ssize_t my_fread(FILE *fp, char *buf, int len) { 
    return fread(buf, 1, len, fp); 
} 
1

Если код, анализирующий контрольную сумму, будет таким же, вы можете сделать это в функцию - это часть внутри фигурной скобки. На мой взгляд, не так уж плохо иметь две отдельные петли, если они называют ту же функцию. Их можно рассматривать как тонкую обертку.

Смежные вопросы