Rolling...

The first two filters were pretty easy. I was on a roll and the other filters were implemented just as quickly…

Now that I could parse 822 addresses blacklists and whitelists were easy to implement. Some refactoring could be done to remove the common ’list’ handling as effectively a blacklist is simply a !whitelist…

Once I had a whitelist filter I decided that it might be useful to have a way of ORing two filters together, so we could filter a filter that does something like “if the message isnt in the whitelist then strip all attachments”… An Or filter was easy to implement and test once I created a mock filter that allowed me to programmatically control what I returned from the call to FilterMessage().

All of this has been developed without a main. There’s no filter program that I can run. I just haven’t needed one. The test harness does enough to let me test the code and I haven’t yet got to the point where the only code left to write is main.

Now that I have a bunch of filters I need to have an easy way to build the filter chain. A filter chain test comes into existence and I write some tests to add filters to the chain. A filter chain is simply a group of filters that are ANDed together. I write an AND filter. When you add a filter to the chain it creates an AND filter from the filter that it has and the new filter that you give it. When the filter chain is run it simply runs the single filter that it contains and this, in effect, is a chain of filters connected by AND filters… As long as a filter returns true the next is run, until we get to the end. The one wart is the end. I created a NULL filter, a filter that does nothing and simply returns true, this becomes the first filter in the chain and the special case code goes away…

[interesting aside: so I’m writing the stuff about how the NULL filter meant I didn’t have a special case anymore and I couldn’t remember if the filter chain was built by adding new filters to the front of the chain (the NULL filter is the last filter called) or by adding filters to the back of the chain (the NULL filter is the first to be called). I’d written that it was the back, and the back seems sensible; when you look at the code f.AddFilter(f1); f.AddFilter(f2); it looks to me like a the filters should be executed in f1, f2 order… Anyway, I couldn’t remember so I went to look at the test (not the code, the test!) weird… The test didnt tell me, I hadn’t bothered to write a multiple filters in the chain test (doh!, I had multiple AND filter tests so I knew the underlying code worked but…). I added a test and discovered that the code actually added the new filters to the front. So I fixed the code… I find that whole little episode interesting as it’s not how I would have expected to have behaved a month or two ago…]

So we have a filter chain, now we just need something that builds a chain for a mailbox based on the filter configuration and then runs all the messages in the mailbox through the chain…