The one where I dont use XML

| 0 Comments

So I have an email filter that can write messages to another mailbox. I need to supply it, and all other filters that I might write, with some configuration data. I could use XML but I dont...

Filters are given an instance of an IFilterDataManager when they're created; the idea being that they can obtain any configuration data that they need from it. More advanced filters might also want to write data back once they're done, but that's a story for another day...

class IManageFilterData 
{
   public :

      virtual IReadableFilterData *GetReadableData(
         const std::string &dataName) = 0;

      virtual IWriteableFilterData *GetWriteableData(
         const std::string &dataName,
         const size_t dataSize) = 0;

   protected :

      virtual ~IManageFilterData() {}
};

A filter might have more than one kind of data it needs, so it can ask for it by name. The IReadableFilterData interface is fairly straight forward:

class IReadableFilterData 
{
   public :

      virtual size_t GetDataSize() = 0;

      virtual bool ReadData(
         BYTE *pDataBuffer,
         const size_t bufferSize,
         size_t &bytesSupplied) = 0;

      virtual std::string ReadString() = 0;

   protected :

      virtual ~IReadableFilterData() {}
};

ReadData() is where it's at. The filter can grab any kind of configuration data as a block of bytes and it can ask how big the data is first, if it wants. The ReadString() function is a bit of a cop out, or 'ease of use' method... If the filter can handle its data as a single string then it can call this rather than managing a buffer itself. I expect this may get refactored away at some point.

I could pass the config data as XML. But at present I dont really need to and I dont think it adds anything possitive to the design to tie the interface to XML. The configuration for the message writer filter is simple, just a single destination mailbox name. Other stuff might be binary (a word frequency table, perhaps). Besides the config data is treated as a opaque blob of bytes by everything except the thing that makes it and the thing that consumes it. The interface as given can handle XML if the writer and reader both treat the byte blob as XML...

With this interface fleshed out, a mock object or two in place and a quick change to the filter object itself I can configure the object and the test for different mailboxes passes.

I now have a single filter that takes a message and writes it to a mailbox. This could be used to split a mailbox by chaining two of these filters together and having each write to a different destination.

Leave a comment