Added Adapter Class to DKit

DKit Laboratory

Today I spent the time to finish up the addition of the adapter class to DKit. The idea is pretty simple: place a source and sink back-to-back and have their template types independent, and there you go! The multiple inheritance virtual template class is a little tricky in getting all these templates working, but I got it - eventually.

The original implementation was designed to simply use the API of the source and sink, but then I ended up getting into trouble with the accessing of protected methods in the source and sink, so I needed to lean a little more heavily on the actual implementations of the source and sink. This works well, too, as we then only have one codebase that we have to maintain - and that's always a good thing.

The implementation is really just a combination of the source and sink, but it affords me the flexibility of making a base class that takes a certain type, and generates a certain type, and with a little template specialization, it all comes together very simply and easily for the user.

I worked up a simple test adapter, and it's pretty clean:

  template <class TIN, class TOUT> class MyAdapter :
    public dkit::adapter<TIN, TOUT>
  {
    public:
      MyAdapter() { }
 
      /**
       * This is the main receiver method that we need to call out to
       * a concrete method for the type we're using. It's what we have
       * to do to really get a virtual template class working for us.
       */
      virtual bool recv( const TIN anItem )
      {
        return dkit::adapter<TIN, TOUT>send(convert(anItem));
      }
 
      /**
       * This method is called when we get a new datagram, and because
       * we are expecting to instantiate this template class with the
       * type 'T' being a <datagram *> this is the method we're expecting
       * to get hit. It's just that simple.
       */
      std::string convert( const datagram *dg ) {
        std::string     out = "<null>";
        if (dg != NULL) {
          std::cout << "converting: " << dg->contents() << std::endl;
          out.assign(dg->what, dg->size);
        }
        return out;
      }
  };

As with the sink, we need to include the recv() method, and then call the specialized method that will do the actual work. In many cases, this specialized method can be a virtual method, making the implementation of the subclasses even simpler. I think it's a pretty solid design, and I'm happy with it.

I'd still like to add a UDP transmitter, and I hope to get to that tomorrow - just to round out the library for completeness.