How do I include two different versions of the same header?

I am writing code to convert files from a proprietary file format to another generic one. My goal is to support multiple versions of the manufacturer file format.

I have several versions of the same proprietary headers. Headers define the various structures that make up the main file header (the file is just a large header followed by the raw data).

I need to read the first 4 bytes of a source file to determine the version of the file. The version of the file, in turn, tells me which version of the C-struct was used to create the file.

Problems:

  • I cannot change my own headers
  • Headers don't use namespaces or classes
  • There is a good portion of macros defined in headers

Possible solutions:

  • Create different converter binaries for each type of file version :-(
    • Inconvenient for user and developer
  • Dynamically loading libraries for each version
    • The converter is plugin oriented, so a lot of this is already happening.

I tried to hack namespaces:

namespace version1 {
    #include "version1.h"
}

namespace version2 {
    #include "version2.h"
}

int main (void) {
    version1::header *hdr = new version1::header;
    return 0;
}

      

But it won't work because of the inclusion of guards and because several macros are redefined in each header.

Is there an elegant way to handle this?

+2


source to share


1 answer


You can use two different source files along with the forward declaration:

// Forward declare in main.cpp:

namespace version1
{
   struct header;
}

namespace version2
{
   struct header;
}

      


// version1.cpp:

namespace version1
{
      #include <version1.h>
}

version1::header* new_v1_header()
{
   return new version1::header;
}

// other functions using `version1::header`

      


// version2.cpp:

namespace version2
{
      #include <version2.h>
}

version2::header* new_v2_header()
{
   return new version2::header;
}

// other functions using `version2::header`

      

Another alternative is to implement a wrapper class that has a base class that is just an empty wrapper:

class header_base
{
     virtual int func1(char *stuff) = 0; 
     ... many other virtual functions. 
};

// Create implementation of header_v1 or header_v2:
header_base* make_header(unsigned int magic);

      



header_base.cpp:

#include "header_v1.h"
#include "header_v2.h"

header_base* make_header(unsigned int magic)
{
    switch(magic)
    {
       case Magic_V1: 
          return new header_v1;
       case Magic_V2: 
          return new header_v2;
       default:
          assert(0);
          return 0;
    }
}

      

and then implement in two separate

in headerv1.h:

class header_v1 : public header_base
{
    int func1(char *stuff);
    ... 
};

      

header_v1.cpp:

#include "header1.h"

int header_v1::func1(char *stuff)
{
   ... 
   return 17;
}

      

And similarly for header_v2.h and header_v2.cpp.

+5


source







All Articles