Resolving Embedded XML

Illustration

One of my fetishes is including as much resources as possible within the executable. This is fairly easy to do with Visual Studio. Just select desired file and change Build Action property to Embedded Resource.

Biggest benefit is that you can count on file always being there. There is no need to add file to installer nor to do error handling. And, even when you need to have user-modifiable files, you can always tuck away safe defaults far out of reach of an inexperienced user.

When you have XML file stored as this, loading is as easy as it gets:

var doc = new XmlDocument();
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("project.example.xml");
doc.Load(stream);

However, when you have that same file linked to it’s DTD (Document Type Definition) things get ugly. Only thing that we get with our function is FileNotFoundException with Could not find file 'C:\somepath\example.dtd'. Things do not change even when DTD is embedded next to XML. As you can see from exception, our XmlDocument is stubbornly reading DTD from disk instead from resources.

Easiest solution is to delete referring DOCTYPE from XML document. However, that is double-edged sword since that also means that you lose quite a good helping hand in detecting early errors. I will not even go into how (properly created) DTD can be huge help with intellisense during XML editing.

Better solution would be to use XmlDocument’s existing XmlResolver property. XmlResolver is what actually handles from where each stream is read. If we inherit that class we can make critical change to read DTD from resource stream instead from file system. And it all fits in single overridden function:

public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) {
    var fileName = absoluteUri.Segments[absoluteUri.Segments.Length - 1];
    var resourceName = "project." + fileName;
    var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
    return resourceStream;
}

Code will just check which file name is required and return matching embedded resource stream. Loading XML stays almost same:

var doc = new XmlDocument();
doc.XmlResolver = MyResolver();
var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("project.example.xml");
doc.Load(stream);

P.S. Do notice that above are excerpts from little bit bigger code. Full sample is available for download.

Pogo PICKit

Illustration

Whenever I design board with PIC I need ICSP connector. And connectors take space.

Therefore I started used Au Group Electronics connector soldered to simple cable that plugged into PICkit. By using pogo pins I could put six through-hole pads on borad and have connectivity. Works nicely and it is as cheap as it goes.

That did worked but connector was weak spot. No matter how you hold it, there was need to re-solder broken wire every few weeks. Not too annoying, I guess…

Well, I found myself a new personal favorite.

Mill-max has a nice pogo connector “clearly” named 829-22-006-20-001101. Out of box it comes as 90° PCB-mountable connector but, with the help of pliers, I straightened those pins and they fit perfectly into PICkit 3 (they actually hold better than straight pins). Now I can press onto my board’s pads with whole PICkit and that feels much better.

There is only small issue of fitting into snug spaces. With cable you can get into any space, with this “connector” things work better if connector is at board’s edge. But it is small price to pay.

P.S. Connector is available from both DigiKey and Mouser.

P.P.S. Yes, connector works with both PICkit 2 and PICkit 3.

SHA-1 Sum Every File

Easiest way to check whether file is valid after download is to grab it’s SHA-1 sum. Most commonly it has same name as file but with additional .sha1 extension (e.g. temp.zip would have SHA-1 sum in temp.zip.sha1). One annoyance is how to generate all those .sha1 files…

To make my life little bit easier, I made a bash script. This script will go through given directories and create all SHA-1 sums. I use content and download directories in this case:

#!/bin/bash
for file in ~/public_html/{content,download}/*
do
    if [ -f "$file" ]
    then
        if [ ${file: -5} != ".sha1" ]
        then
            file1=$file
            file2="$file1.sha1"
            file1Sum=`sha1sum $file1 | cut --delimiter=' ' -f 1`
            if [ -e "$file2" ]
            then
                file2Sum=`cat $file2`
                if [ "$file1Sum" == "$file2Sum" ]
                then
                    echo "  $file1"
                else
                    echo "X $file1"
                    echo "$file1Sum" > "$file2"
                fi
            else
                echo "+ $file1"
                echo "$file1Sum" > "$file2"
            fi
        else
            file1=${file%.sha1}
            file2=$file
            if [ ! -e "$file1" ]
            then
                echo "- $file1"
                rm "$file2"
            fi
        fi
    fi
done

Probably some explanation is in order. Script check each file in content and download directories. If file ends in .sha1 (bottom of the script), we will just remove that file and log action with minus (-) sign. This serves as clean-up for orphaned SHA-1 sums.

If file does exist, we need to check existing SHA-1 sum. If there is no sum script will just create one and log it with plus (+) sign. If sum does exist, script compares it with newly generated value. If both match, there is nothing to do, if they do not match, that is logged with X character.

Example output would be:

  /public_html/download/qtext301.exe
+ /public_html/download/qtext310.exe
X /public_html/download/seobiseu110.exe
- /public_html/download/temp.zip

Here we can see that sum for qtext301.exe was valid and no action was taken. Sum for qtext310.exe was added and one for seobiseu110.exe was fixed (it’s value didn’t match). File temp.zip.sha1 was removed since temp.zip does not exist anymore.

P.S. While this code is not perfect and it might not be best solution, it does work for me. :)

I Like Unique Identifiers

Illustration

As I was finishing my order of MSDN magazine I was puzzled with one field. It said “In lieu of a signature, we require a unique identifier. In what month were you born?”

I am not quite sure in what universe month of birth is even close to being unique…

P.S. It is January.

IPv6 Multicast

Last post dealt with sending same message to multiple clients in IPv4. Since IPv4 pool is almost gone, we might as well see how to do it in IPv6.

Believe it or not, code is virtually identical:

this.Socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
this.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
this.Socket.Bind(new IPEndPoint(IPAddress.IPv6Any, 65535));
this.Socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.AddMembership, new IPv6MulticastOption(IPAddress.Parse("ff08::1")));

Just use socket as you would normally do.

Code example is available for download.

P.S. For this example I used ff08::1 as multicast address. You might want to change this to something not as usual as this (but compliant to ffx8::/16). E.g. ff28::1:2:3:4:5 might do the trick.