Click here to Skip to main content
16,016,882 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
Dear friends, I am trying to implement a program that reconstructs a binary file, starting from the old file and a file of differences. The work is based on the ingenious thesis Olin Percival, Naive differences of executable code, http://www.daemonology.net/bsdiff/ , 2003. I want to use the rebuilder (bspatch) on a microcontroller ARM M4. I'm trying to eliminate disk access with operations on simple vectors. The operation is not trivial because the Olin program is complicated! Of course in addition to the file pointer, the Olin program uses functions to access the file, such as fgetc FSEEK that must be replaced. To start I am working in C in visual studio and when the program will work on the PC i will move it on ARM M4.
To begin with, I add static vectors of char as long as the files in input,then I copy-paste the files in to the vectors. From this point on I no longer want to make disk accesses. However, the program keeps making unwanted disk access.

Has anyone ever replaced a file pointer with a vector of char to use only RAM?

Look the original program of Olin (found in the link) there is a Visual Studio project.

Thank You and Happy Happy Happy New Year
Stefano Fredella

C#
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>
Posted
Updated 26-Dec-15 12:26pm
v2
Comments
Sergey Alexandrovich Kryukov 26-Dec-15 10:54am    
Please, what is your question? "Has anyone ever replaced..?"?! This is not a question on any of the topics of this forum. And why would you even need to know anyone who "replaced"? You need someone who cold help you, and this is a totally different story. To get help here, you need to ask some question; and you are not even trying to do so; all your post is reduced to stating that some program seems to be too complicated to you. Sorry about that.

In other words, you did not write anything which could help to help you.

—SA
Member 11869825 27-Dec-15 9:35am    
Thank You, I hope that my problem now is clearer to all.
Philippe Mori 26-Dec-15 18:05pm    
Mainly, I think you have to rewrite the code. Or use something like a RAM disk if the target OS have that...
Member 11869825 27-Dec-15 9:46am    
Unfortunately my target os don't have ram disk or equivalent, so i want read the file s only for debug with visual studio and than work on ram. In the target project the data come from serial port Uart and is stored in a ram memory page. When the debug program will run on pc i will move it to microcontroller ARM.

Abstraction.

You need an abstraction layer between the code and the actual data (file or memory). You'll need to write two implementations of this abstraction layer - one for a file and the other for memory. Your comments state the need for random access so this layer will need to support seek.

This is much more easily done in C++. If you are limited to C, use a struct with function pointer members - one each for open, close, read, write, and seek.

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);
};


Next, you'd write five functions that call the standard C FILE * API. Get that working first as it will be the easiest way to verify you have not broken anything.

Finally, write five functions that use memory - probably the heap - to do the same.
 
Share this answer
 
hi did you resolved above issue ?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900