Member 11869825 Ответов: 2

Перестроить файл из исходного файла и файла различий в оперативной памяти


Дорогие друзья, я пытаюсь реализовать программу, которая восстанавливает двоичный файл, начиная со старого файла и файла отличий. Работа основана на гениальном тезисе Олина Персиваля «Наивные отличия исполняемого кода», http://www.daemonology.net/bsdiff/, 2003. Я хочу использовать восстановитель (bspatch) на микроконтроллере ARM M4. Пытаюсь исключить доступ к диску с помощью операций с простыми векторами. Операция нетривиальная, потому что программа Олина сложна! Конечно, помимо указателя файла, программа Olin использует функции для доступа к файлу, такие как fgetc FSEEK, которые необходимо заменить. Для начала я работаю на C в Visual Studio, и когда программа будет работать на ПК, я перенесу ее на ARM M4.
Для начала я добавляю статические векторы char до тех пор,пока файлы находятся во входных данных, а затем копирую-вставляю файлы в векторы. С этого момента я больше не хочу делать доступ к диску. Однако программа продолжает делать нежелательный доступ к диску.

Кто-нибудь когда-нибудь заменял указатель файла вектором char, чтобы использовать только оперативную память?

Посмотрите оригинальную программу Olin (найденную по ссылке)там есть проект Visual Studio.

Спасибо и счастливого счастливого Нового года
Стефано Фределла

Ok, I try to explain one specific problem:
 
I have these two functions and i do not want pass FILE* f. I want pass a chars vector 
How can I change that?
 
<pre lang="c++">
typedef void BZFILE;
 
BZFILE* BZ_API(BZ2_bzReadOpen) 
                   ( int*  bzerror, 
                     FILE* f, 
                     int   verbosity,
                     int   small,
                     void* unused,
                     int   nUnused )
{
   bzFile* bzf = NULL;
   int     ret;
 
   BZ_SETERR(BZ_OK);
 
   if (f == NULL || 
       (small != 0 && small != 1) ||
       (verbosity < 0 || verbosity > 4) ||
       (unused == NULL && nUnused != 0) ||
       (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
      { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
 
   if (ferror(f))
      { BZ_SETERR(BZ_IO_ERROR); return NULL; };
 
   bzf = malloc ( sizeof(bzFile) );
   if (bzf == NULL) 
      { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
 
   BZ_SETERR(BZ_OK);
 
   bzf->initialisedOk = False;
   bzf->handle        = f;
   bzf->bufN          = 0;
   bzf->writing       = False;
   bzf->strm.bzalloc  = NULL;
   bzf->strm.bzfree   = NULL;
   bzf->strm.opaque   = NULL;
 
   while (nUnused > 0) {
      bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
      unused = ((void*)( 1 + ((UChar*)(unused))  ));
      nUnused--;
   }
 
   ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
   if (ret != BZ_OK)
      { BZ_SETERR(ret); free(bzf); return NULL; };
 
   bzf->strm.avail_in = bzf->bufN;
   bzf->strm.next_in  = bzf->buf;
 
   bzf->initialisedOk = True;
   return bzf;   
}
 
int BZ_API(BZ2_bzRead) 
           ( int*    bzerror, 
             BZFILE* b, 
             void*   buf, 
             int     len )
{
   Int32   n, ret;
   bzFile* bzf = (bzFile*)b;
 
   BZ_SETERR(BZ_OK);
 
   if (bzf == NULL || buf == NULL || len < 0)
      { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
 
   if (bzf->writing)
      { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
 
   if (len == 0)
      { BZ_SETERR(BZ_OK); return 0; };
 
   bzf->strm.avail_out = len;
   bzf->strm.next_out = buf;
 
   while (True) {
 
      if (ferror(bzf->handle)) 
         { BZ_SETERR(BZ_IO_ERROR); return 0; };
 
      if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
         n = fread ( bzf->buf, sizeof(UChar), 
                     BZ_MAX_UNUSED, bzf->handle );
         if (ferror(bzf->handle))
            { BZ_SETERR(BZ_IO_ERROR); return 0; };
         bzf->bufN = n;
         bzf->strm.avail_in = bzf->bufN;
         bzf->strm.next_in = bzf->buf;
      }
 
      ret = BZ2_bzDecompress ( &(bzf->strm) );
 
      if (ret != BZ_OK && ret != BZ_STREAM_END)
         { BZ_SETERR(ret); return 0; };
 
      if (ret == BZ_OK && myfeof(bzf->handle) && 
          bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
         { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
 
      if (ret == BZ_STREAM_END)
         { BZ_SETERR(BZ_STREAM_END);
           return len - bzf->strm.avail_out; };
      if (bzf->strm.avail_out == 0)
         { BZ_SETERR(BZ_OK); return len; };
 
   }
 
   return 0; /*not reached*/
}
static Bool myfeof ( FILE* f )
{
   Int32 c = fgetc ( f );
   if (c == EOF) return True;
   ungetc ( c, f );
   return False;
}
</pre>

Sergey Alexandrovich Kryukov

Пожалуйста, какой у вас вопрос? "Кто-нибудь когда-нибудь заменял...?"?! Это не вопрос ни по одной из тем этого форума. И зачем вам вообще знать кого-то, кто"заменил"? Вам нужен кто-то, кто поможет вам, а это совсем другая история. Чтобы получить здесь помощь, вам нужно задать какой-то вопрос; и вы даже не пытаетесь это сделать; весь ваш пост сводится к утверждению, что какая-то программа кажется вам слишком сложной. Сожалеть об этом.

Другими словами, вы не написали ничего, что могло бы помочь вам.

—СА

Member 11869825

Спасибо, надеюсь, что моя проблема теперь всем понятна.

Philippe Mori

Главным образом, я думаю, что вы должны переписать код. Или используйте что-то вроде RAM-диска, если это есть в целевой ОС...

Member 11869825

К сожалению, моя целевая ОС не имеет ram-диска или эквивалента, поэтому я хочу читать файл s только для отладки с помощью visual studio, а не работать с оперативной памятью. В целевом проекте данные поступают из последовательного порта Uart и хранятся на странице оперативной памяти. Когда отладочная программа будет работать на ПК, я перенесу ее на микроконтроллер ARM.

2 Ответов

Рейтинг:
2

Member 13324712

привет, вы решили вышеуказанную проблему ?


Рейтинг:
0

bling

Абстракция.

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

Это гораздо проще сделать в C++. Если вы ограничены C, используйте структуру с элементами указателя функции - по одному для открытия, закрытия, чтения, записи и поиска.

typedef void *handle_t;

struct indirect
{
    bool (*open)(const char *name, handle_t &handle);
    void (*close)(handle_t handle);
    bool (*read)(handle_t handle, unsigned char *data, size_t size, size_t *copied);
    bool (*write)(handle_t handle, const unsigned char *data, size_t size, size_t *copied);
    bool (*seek)(handle_t handle, long seek);
};


Затем вы напишете пять функций, вызывающих стандартный C-файл * API. Сначала заставьте это работать, так как это будет самый простой способ убедиться, что вы ничего не сломали.

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