Archive for July, 2008

(This is the continuation)

An event source could now simply instantiate and inherit this multiple times to become a source for multiple sources(!), to make the example smaller I present a class with one source (but with two events!).

   1: class DispatchablePipeIOListener
   2: {
   3: public:
   4:     virtual void onInput(class DispatchablePipe& pipe) = 0;
   5:     virtual void onOutput(class DispatchablePipe& pipe) = 0;
   6: };
   7:  
   8: class DispatchablePipe : public Pipe, protected AFW::IOEventHandler, public ListenableEventSource<DispatchablePipeIOListener>
   9: {
  10: public:
  11:     DispatchablePipe(void);
  12:     virtual ~DispatchablePipe(void);
  13:  
  14: protected:
  15:     typedef enum eContext
  16:     {
  17:         INPUT = 1,
  18:         OUTPUT = 2,
  19:     } Context;
  20:  
  21:     // AFW::IOEventHandler
  22:     virtual void handleInput(AFW_IO_HANDLE);
  23:     virtual void handleOutput(AFW_IO_HANDLE);
  24:     virtual AFW_IO_HANDLE getHandle();
  25:  
  26:     virtual int dispatchEvent(DispatchablePipeIOListener& l, const int& c, void* userParam);
  27:  
  28: };

Now a philosophical problem arises for me. Due to the fact that the template needs to know about the Listener interface (well it doesn’t really, but since I also want to avoid any type of casts it does, otherwise I could just void it..) I have to declare this outside the event source class (DispatchablePipe) , I normally like to put the source interface inside the source classes. The other annoying problem that arises is that because the event function is general I need to supply some context data to it, which I suppose is allright as long as it is a simple int, otherwise I need to delcare yet another class ouside the source… These problems wouldn’t be a problem if I instead would choose to aggregate the ListenerList above directly.

The beauty is of course that I get the add/removeListener functionality easily just by inheriting and providing a dispatchEvent trampoline. But I am not entirely sure it is worth the cost of extra complexity just to avoid typing addListener/removeListener and a member variable for each event type.

The event source looks internally like this

   1: void DispatchablePipe::handleInput(AFW_IO_HANDLE handle)
   2: {
   3:     fireNewEvent(INPUT);
   4: }
   5:  
   6: void DispatchablePipe::handleOutput(AFW_IO_HANDLE handle)
   7: {
   8:     fireNewEvent(OUTPUT);
   9: }
  10:  
  11: int DispatchablePipe::dispatchEvent(DispatchablePipeIOListener& l, const int& c, void* userParam)
  12: {
  13:     switch (c)
  14:     {
  15:     case OUTPUT:
  16:         l.onOutput(*this);
  17:         break;
  18:     case INPUT:
  19:         l.onInput(*this);
  20:         break;
  21:     }
  22:  
  23:     return 0;
  24: }
  25:  

If I instead chose to aggregate it would look like this (I inlined the entire class with empty stuff, but it is not important)

   1: class DispatchablePipe2 : public Pipe, protected AFW::IOEventHandler
   2: {
   3: public:
   4:     DispatchablePipe2(void) {};
   5:     virtual ~DispatchablePipe2(void) {};
   6:  
   7:     class IOListener
   8:     {
   9:     public:
  10:         virtual void onInput(DispatchablePipe2& pipe) = 0;
  11:         virtual void onOutput(DispatchablePipe2& pipe) = 0;
  12:     };
  13:  
  14:     int addListener(IOListener* listener, void* userParam = NULL)
  15:     {
  16:         return m_ioListeners.addListener(listener, userParam);
  17:     }
  18:  
  19:     int removeListener(IOListener* listener)
  20:     {
  21:         return m_ioListeners.removeListener(listener);
  22:     }
  23:  
  24: protected:
  25:     // AFW::IOEventHandler
  26:     virtual void handleInput(AFW_IO_HANDLE) {};
  27:     virtual void handleOutput(AFW_IO_HANDLE) {};
  28:     virtual AFW_IO_HANDLE getHandle() { getSelectableReadFd(); };
  29:  
  30:     typedef enum eEventType
  31:     {
  32:         INPUT = 1,
  33:         OUTPUT = 2,
  34:     } EventType;
  35:     typedef ListenerList<IOListener, DispatchablePipe2, EventType>        IOListenerCollection;
  36:     int dispatchEvent(IOListener& l, const EventType& c, void* userParam)
  37:     {
  38:         switch (c)
  39:         {
  40:         case INPUT:
  41:             l.onInput(*this);
  42:             break;
  43:         case OUTPUT:
  44:             l.onOutput(*this);
  45:             break;
  46:         }
  47:         return 0;
  48:     }
  49:  
  50:     int fireNewEvent(EventType e)
  51:     {
  52:         return m_ioListeners.visit(*this, &DispatchablePipe2::dispatchEvent, e);
  53:     }
  54:  
  55:     IOListenerCollection m_ioListeners;
  56: };

A few forward declaration are gone, the Context parameter is now typed to an enum and I can place the interface inside the source.

It would have been very neat if C++ would have allowed me to have incomplete types in the inheritance class for the class (as they will be complete when the class is fully read), but I am not aware of that that is possible, it would have been the best of both worlds.

(Had to split this up in 2 posts, either Windows Live Writer or spaces is setting a limit)

We have been playing around with the same problem in Java lately. Trying to come up with a neat implementation technique for the listener pattern. today I was a bit intrigued at trying to solve this is C++ as such a class arose that needed a listener interface. Without anonymous classes in C++ this is a bit tricky (not sure anonymous classes are a good thing, but it makes it simpler for small things like the visit function, "closures" in C# 3.5 are very nice though). Speaking of C#, the delegate pattern already solves this and all concurrency problems  and is fully typed requiring zero crud coding so you can focus on the actual event. Don’t know if Java has anything similar.

Anyway, I tried to come up with a reusable class for the listener pattern, and now when I am done I am not sure which solution is better. This post is going to contain a lot of code so bear with me and feel free to advice should you happen to read this blog on the outer rim of the Internet. This could can be made more pluggable and also quite easily made concurrent friendly, but I let that out of the template for now (simple matter of 2 more template arguments to decide the container class and a "mutex" class, which could default to std::vector and NullMutex to get the current behavior).

   1: template<class Listener, typename Receiver, typename Context = int>
   2: class ListenerList
   3: {
   4: public:
   5:     typedef struct sListenerElem
   6:     {
   7:         Listener* listener;
   8:         void*     userParam;
   9:     } ListenerElem;
  10:  
  11:     typedef std::vector<ListenerElem> ListenerCollection;
  12:  
  13: public:
  14:     ListenerList(void) {};
  15:     ~ListenerList(void) {};
  16:  
  17:     typedef typename ListenerCollection::iterator iterator;
  18:  
  19:     iterator begin()
  20:     {
  21:         return m_listeners.begin();
  22:     }
  23:  
  24:     iterator end()
  25:     {
  26:         return m_listeners.end();
  27:     }
  28:  
  29:     int addListener(Listener* listener, void* userParam = NULL)
  30:     {
  31:         int res = -1;
  32:         
  33:         ListenerCollection::const_iterator iter = std::find_if(m_listeners.begin(), m_listeners.end(), ElementFinder(listener));
  34:         if (iter == m_listeners.end())
  35:         {
  36:             ListenerElem elem;
  37:             elem.listener   = listener;
  38:             elem.userParam  = userParam;
  39:  
  40:             m_listeners.push_back(elem);
  41:             res = m_listeners.size();
  42:         }
  43:  
  44:         return res;
  45:     }
  46:  
  47:     int removeListener(Listener* listener)
  48:     {
  49:         ListenerCollection::iterator iter;
  50:         int res = -1;
  51:  
  52:         iter = std::find_if(m_listeners.begin(), m_listeners.end(), ElementFinder(listener));
  53:         if (iter != m_listeners.end())
  54:         {
  55:             m_listeners.erase(iter);
  56:             res = m_listeners.size();
  57:         }
  58:         return res;
  59:     }
  60:  
  61:     typedef int (Receiver::*VisitorFn)(Listener& l, const Context& c, void* userParam);
  62:     int visit(Receiver& r, VisitorFn fn, const Context& c)
  63:     {
  64:         int i = 0;
  65:         for (ListenerCollection::iterator iter = m_listeners.begin(); iter != m_listeners.end(); iter++)
  66:         {
  67:             ListenerElem listener = (*iter);
  68:             (r.*fn)(*listener.listener, c, listener.userParam);
  69:             i++;
  70:         }
  71:         return i;
  72:     }
  73:  
  74: protected:
  75:     class ElementFinder
  76:     {
  77:     public:
  78:         ElementFinder(Listener* listener) { m_listener = listener;}; 
  79:         bool operator() (const ListenerElem& e) { return m_listener == e.listener; };
  80:     private:
  81:         Listener* m_listener;
  82:     };
  83:  
  84:     ListenerCollection        m_listeners;
  85: };

I am pretty happy with this class, except the ElementFinder class, but I am no stl wizard. With this class there are now at least two possible ways to continue. Either the event source itself aggregates this list and adds a addListener/removeListener and directs it towards the list. That’s straight forward and I like it. However in Java we fiddled with an inheritance, so I thought I would try it in C++ as well to see how it would turn out.

   1: template<class Listener, typename Context = int>
   2: class ListenableEventSource
   3: {
   4:  
   5: public:
   6:     ListenableEventSource(void) {};
   7:     virtual ~ListenableEventSource(void) {};
   8:  
   9:     int addListener(Listener* listener, void* userParam = NULL)
  10:     {
  11:         return m_listeners.addListener(listener, userParam);
  12:     }
  13:  
  14:     int removeListener(Listener* listener)
  15:     {
  16:         return m_listeners.removeListener(listener);
  17:     }
  18:  
  19: protected:
  20:     typedef ListenerList<Listener, ListenableEventSource, Context>        ListenerCollection;
  21:     
  22:     virtual int dispatchEvent(Listener& l, const Context& c, void* userParam) = 0;
  23:  
  24:     int fireNewEvent(const Context& c)
  25:     {
  26:         return m_listeners.visit(*this, &ListenableEventSource::dispatchEvent, c);
  27:     }
  28:  
  29:     ListenerCollection        m_listeners;
  30: };

wget for PowerShell

Posted: July 27, 2008 in Computer and Internet

So as it stands I very much like the utilities found in most unix systems. They are often too small and you have to yank them together to make anything useful out of it, sometimes this is great, sometimes not so great. But the wget utility is one of those very neat utilities. There are many ports for windows (e.g. gnuwin32 which by the way is a very useful package unless you are using cygwin/msys).

Either way I thought this would be very simple to accomplish through .Net, and it is

   1: $c = new-object System.Net.WebClient
   2: $c.DownloadFile("http://surfnet.dl.sourceforge.net/sourceforge/gnuwin32/wget-1.10.1.exe", "$pwd\wgetsetup.exe")
That’s it! Well almost, you don’t get any progress. I made a simple search and hit this
 
 
It tries to be a bit more clever about it all, however it didn’t work for the FTP protocol, so I fixed that. Change the line
 
if($res.StatusCode -eq 200) {
 
into
 
if($res.StatusCode -eq 200 -or $res.StatusCode -eq "OpeningData") {
 
So there you have it, a wget light without having to tax around an extra binary (although you will need to tax around the .Net framework instead :=)
 
PowerShell is just awesome, as a terminal it still has ways to go, but as a pipeline idea it is far superior and with the tight integration with .Net and the simplicity to grab .Net classes/objects (and vice versa, it is very simple to add scripting to a .Net application through powershell as it works through objects in the pipeline) it is a sure winner. There are now also incarnations where you can use powershell code in ASP pages instead of VB.

 

I was skimming through the msdn blogs and saw this post

http://www.agileprogrammer.com/dotnetguy/archive/2007/11/22/23853.aspx

As I had the same problem a few months back when first starting using PowerShell I thought I’d post my solution to it here, as I think it is more general. It can take any bat file’s environment and hook into PowerShel

And it will work with all version of Visual Studio (at least those you might still use)

First the function I can call from any shell (32 or 64 bit) to get the environment for the proper version of VS.

   1: function vc([string]$str = "2008")
   2: {
   3:     $path = ""
   4:  
   5:     $64bit = !(gv PSHOME).Value.ToLower().Contains("syswow64")
   6:     $HKLM = "HKLM:\SOFTWARE"
   7:     if ($64bit)
   8:     {
   9:       $HKLM = "HKLM:SOFTWARE\Wow6432Node"
  10:     }
  11:     
  12:     if ($str.contains("9") -or $str.contains("2008"))
  13:     {        
  14:         $path = (gp "$HKLM\Microsoft\VisualStudio\9.0\Setup\VC").ProductDir
  15:         $path = $path + "\vcvarsall.bat"
  16:     }
  17:     elseif ($str.contains("8") -or $str.contains("2005"))
  18:     {
  19:         $path = (gp "$HKLM\Microsoft\VisualStudio\8.0\Setup\VC").ProductDir
  20:         $path = $path + "\vcvarsall.bat"
  21:     }
  22:     elseif ($str.contains("71") -or $str.contains("2003"))
  23:     {        
  24:         $path = (gp "$HKLM\Microsoft\VisualStudio\7.1\Setup\VC").ProductDir
  25:         $path = $path + "\vcvarsall.bat"
  26:     }
  27:     elseif ($str.contains("7") -or $str.contains("2002"))
  28:     {
  29:         $path = (gp "$HKLM\Microsoft\VisualStudio\7.0\Setup\VC").ProductDir
  30:         $path = $path + "\vcvarsall.bat"
  31:     }
  32:     elseif ($str.contains("6") -or $str.contains("98") -or $str.contains("1998"))
  33:     {
  34:         $path = (gp "$HKLM\Microsoft\DevStudio\6.0\Products\Microsoft Visual C++").ProductDir
  35:         $path = $path + "\vcvarsall.bat"
  36:     }
  37:     if ($path.length -gt 0)
  38:     {
  39:         echo "Setting environment for $path"
  40:         envbat "$path"
  41:     }
  42: }

And then the ugly but functional envbat function which can take any bat file and "steal" its environment and add it to psh.

   1: function envbat
   2: {
   3:     $oldenv = @{}
   4:     $newenv = @{}
   5:     get-childitem env: | foreach-object { $oldenv[$_.Key] = $_.Value }
   6:     
   7:     $cmd, [string]$args = $args
   8:     cmd /c " `"$cmd`" $args > nul && set " | Foreach-Object {   
   9:         if($_ -match "^(.*?)=(.*)$")  
  10:         {   
  11:             $newenv[$matches[1]] = $matches[2]
  12:         }
  13:     }
  14:  
  15:     $newenv.Keys |
  16:       foreach-object {
  17:         if (!$oldenv.ContainsKey("$_")) {
  18:             echo "Adding $_"
  19:             set-item -Path env:$_ -Value $newenv[$_]
  20:         } elseif ($oldenv[$_] -ne $newenv[$_]) {
  21:             echo "Changing $_"
  22:             set-item -Path env:$_ -Value $newenv[$_]
  23:         }
  24:     }
  25:  
  26:     $oldenv.Keys |
  27:       foreach-object {
  28:         if (!$newenv.ContainsKey("$_")) {
  29:             echo "Removing $_"
  30:             remove-item -Path env:$_
  31:         }
  32:     }
  33: }  
 

So there you have it. A quick explanation, it first remember the current psh environment, runs the batch file followed by "set" (line 8) which produces a list of all environment variables from the cmd shell. Walks through and stores those that match the regexp. The rest is just a matter of updating the psh environment with the cmd keys.

Vista unidentified network

Posted: July 10, 2008 in Uncategorized

 

Anyone that has tried to install a loopback adapter of any sort in Vista have probably hit the firewall profile annoyance. It will set your firewall profile to "Public" whenever it cannot identify a network. That has bugged me for quite awhile (especially if you install the loopback remotely connected to work thus losing your connection because RDP only was open on the domain profile..) but I never got around to be annoyed enough to fix it, I simply turned off the loopback as I wasn’t using it any longer. However today I decided to install VMWare again on my dev box, VMWare have the same problem as it install 2 networks for your benefit, unfortunately it sets your firewall profile to "Public".

Last time I tried to solve this I simply set the default gateway to point to the adapter itself. But I found this to be a poor solution as it adds default routes to my routing table that I don’t want there (especially since I have a multi homed setup at home, so I need those routes and metrics static!), so I ended up disabling the VMNet as I didn’t use it at the time, but now I want to use it so simulate an entire system locally in VMWare, so today I finally dug in a bit and found the gem!

In Ndis you can change the device type to become an end point device. This basically means that the adapter isn’t a connection to a reachable network, Vista will thus not try to discover and manage it.

Add the DWORD key "*NdisDeviceType" with value 1 to
HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318005}

http://msdn.microsoft.com/en-us/library/bb201634.aspx

So there you have it! A happy route table and an even happier firewall!

My first blog

Posted: July 10, 2008 in Uncategorized

 

Hello cyberworld!

I thought I’d start a blog, not so much because I have things I need to express but more as a digital memory and log for myself. I often stumble upon a lot of technical quirks and interesting things (at least I view them as such). I tend to pile them up in categorized favorites in my browser and sync them around to all machines I commonly use. A problem with that is that it is not very searchable as a favorite is only described by its title. I thought I would instead add more content to this so called memory. If it is useful for someone else even better for them, if you have something to add even better for me =)

This will be a technical blog mostly about software engineering and the hurdles and solutions I come across. Sometimes I might also venture off this memory path to add some opinions of my own, those that know me probably knows that I have many and they escape my mind and become vocalized when you would expect the least =). It will also contain solutions to computer problems that I come across in my developing endeavors.

Well that was the introduction, let’s see if I can stick to it!